# Click2Shell: WordPress Theme-Preview CSRF/Selector-Injection Chain to Forced Theme Install

> PWN AI researcher Paulos Yibelo disclosed Click2Shell, a WordPress core flaw where a crafted theme-install URL clicked by a logged-in administrator abuses a jQuery-selector/theme-slug parsing mismatch to silently force-install an inactive WordPress.org theme, then chains that with a nonce/capability-free AJAX plugin-installer in the Mobile Repair Zone theme (v2.5.4) to reach remote PHP code execution. WordPress 7.1.1 (September 17, 2026) patched the core selector-injection flaw; no CVE had been assigned at publication (September 18, 2026) and no in-the-wild exploitation has been reported.

- **Published:** 2026-09-21T00:00:00Z
- **Last reviewed:** 2026-09-21T00:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-2597
- **Card image:** https://intel.threadlinqs.com/og/threat/threat-intel-click2shell-wordpress-rce-tl-2026-2597.webp?v=e3e6dc7d (Threadlinqs threat intel: Click2Shell WordPress Theme-Inject to RCE: Detection & IOCs (TL-2026-2597) — Critical severity, 12 IOCs, 9 detection rules.)
- **ID:** TL-2026-2597
- **Severity:** CRITICAL (CVSS 9.3)
- **Category:** VULNERABILITY
- **Status:** PATCHED
- **Detections:** 9 (1 shown free below) · **IOCs:** 12

## Description

Click2Shell chains two separate weaknesses into a one-click, pre-authenticated-victim path to remote code execution on WordPress sites. The root cause is a parsing mismatch: when a theme slug is supplied via the `theme` query parameter to `/wp-admin/theme-install.php`, the server-side WordPress.org Themes API canonicalizes the value into a legitimate theme slug, but the admin-side JavaScript in `/wp-admin/js/theme.js` builds a DOM/jQuery selector directly from the raw, un-sanitized URL value: `$( 'div[data-slug="' + slug + '"]' ).trigger( 'click' )`. By injecting CSS-selector metacharacters into the parameter (the published PoC uses `twentytwenty%22%5D%3E%2A%3E%2A%3E%2A%2F%2A`, which decodes to `twentytwenty"]>*>*>*/*`), an attacker escapes the intended attribute selector and redirects the programmatic click onto the theme card's Install control. Because the server independently resolves the parameter to a real, legitimate WordPress.org theme, the request appears benign to WordPress core even though the browser was tricked into clicking Install on an attacker-chosen theme.

When an authenticated administrator opens the crafted link (directly, via an embedded iframe, or as a chained XSS sink), this selector-injection primitive causes their own browser, running with their own session, to silently install (but not activate) an attacker-chosen theme from the public WordPress.org directory -- no confirmation dialog is shown, and because the site's visibly active theme never changes, administrators have no visual indicator that anything happened. A second crafted link then loads the WordPress Customizer preview for that inactive theme (`/wp-admin/admin-ajax.php?wp_customize=on&customize_theme=<slug>`), which is sufficient to execute the theme's `functions.php` even though the theme was never formally activated -- a pre-activation execution path distinct from, and generally overlooked relative to, ordinary theme-activation review. PWN AI's proof-of-concept paired this pre-activation execution with a real-world theme defect: Mobile Repair Zone v2.5.4 registers an AJAX action, `wp_ajax_mobile_repair_zone_install_and_activate_plugin`, whose handler `mobile_repair_zone_install_and_activate_plugin()` performs no `check_ajax_referer()` nonce verification and no `current_user_can()` capability check. The handler accepts attacker-supplied `plugin_details[plugin_url]`, `plugin_details[plugin_text_domain]`, and `plugin_details[plugin_main_file]` POST parameters and will fetch a base64-encoded plugin ZIP from an arbitrary, attacker-controlled external URL (no domain allowlist or origin check), extract it, and load its PHP entry point, giving the attacker arbitrary PHP execution under the web server's privileges.

PWN AI further documented that this missing-nonce/missing-capability pattern on a `wp_ajax_*` installer handler is not unique to Mobile Repair Zone: the researchers identified more than 40 additional third-party WordPress themes registering similarly unprotected plugin/theme-installer AJAX actions, meaning the RCE half of the chain generalizes well beyond the single theme used in the published PoC and the real-world blast radius depends on which of these themes a given site has installed (active or not). PWN AI rated the isolated forced-install primitive High (CVSS 3.1, 7.1) and the complete demonstrated chain to pre-activation code execution Critical (CVSS 3.1, 9.3, with a UI:R -- user interaction required -- component lowering the score from a theoretical maximum); Patchstack's independent write-up corroborates the 9.3 figure, while The Hacker News' coverage instead reports 9.6 for the full chain -- both accounts agree on 7.1 for the isolated core flaw. Because the WordPress core bug alone does not accept an arbitrary theme ZIP, full remote code execution depends on chaining it with a second, independently-vulnerable theme or plugin such as Mobile Repair Zone; the core flaw's real-world severity is therefore a function of what vulnerable themes/plugins are installed on a given site. Exploitation requires an administrator to click a link (via phishing or a chained XSS) and requires the target site to permit file modifications (sites with `DISALLOW_FILE_MODS` enabled are not exploitable for the RCE portion). WordPress fixed the core issue in 7.1.1 (released September 17, 2026, alongside ten other, unrelated security fixes credited to separate researchers) by scoping the vulnerable selector strictly to real `.theme` DOM elements and passing the slug through jQuery's `$.escapeSelector()` before insertion (`$( 'div.theme[data-slug="' + $.escapeSelector( slug ) + '"]' ).trigger( 'click' )`), treating attacker input as literal text rather than structural selector syntax. No CVE identifier had been assigned as of the September 18, 2026 public disclosure, though WordPress indicated one would follow; there is no evidence of in-the-wild exploitation, and Patchstack noted its customers received automatic virtual-patch protection ahead of the vendor fix.

## MITRE ATT&CK

- T1587.004 Exploits
- T1588.006 Vulnerabilities
- T1583.006 Web Services
- T1566.002 Spearphishing Link
- T1190 Exploit Public-Facing Application
- T1204.001 Malicious Link
- T1203 Exploitation for Client Execution
- T1059.007 JavaScript
- T1505.003 Web Shell
- T1564 Hide Artifacts

## Free detection (Splunk SPL, Microsoft KQL, Sigma)

**WordPress theme-install.php CSS/jQuery Selector-Injection URL (Click2Shell Forced-Install Primitive)** (`TL-2026-2597-SPL-001`)

Detects an HTTP request to /wp-admin/theme-install.php whose theme query parameter contains CSS-selector metacharacters (", ], >, *) either raw or URL-encoded. This is the core Click2Shell exploitation primitive: WordPress core's Themes API canonicalizes the slug server-side while pre-7.1.1 admin JS (/wp-admin/js/theme.js) builds a jQuery selector from the raw un-sanitized value, letting an attacker escape the attribute selector (e.g. twentytwenty%22%5D%3E%2A%3E%2A%3E%2A%2F%2A) and redirect a logged-in administrator's own click onto the Install control for an attacker-chosen theme. Requires the request to be observed against an authenticated wp-admin session (referer/cookie present) to distinguish from scanner noise.

- **Languages:** Splunk SPL, Microsoft KQL, Sigma
- **ATT&CK:** T1190, T1566.002, T1204.001
- **Data sources:** wordpress_access_logs, apache_nginx_access_logs, azure_app_service_http_logs, waf_logs
- **Severity:** critical
- **Confidence:** high

### Splunk SPL

```spl
index=web (sourcetype=wordpress:access OR sourcetype=access_combined OR sourcetype=access_common)
  uri_path="*/wp-admin/theme-install.php"
| rex field=uri_query "theme=(?<theme_param>[^&]+)"
| eval theme_param_decoded=urldecode(theme_param)
| where match(theme_param, "(?i)(%22|%5d|%3e|%2a)") OR match(theme_param_decoded, "[\"\]>*]")
| where isnotnull(cookie) OR match(http_user_agent, "(?i)mozilla") 
| eval has_admin_cookie=if(match(cookie, "(?i)wordpress_logged_in"), "true", "false")
| stats count min(_time) as first_seen max(_time) as last_seen values(theme_param) as theme_params values(http_user_agent) as user_agents values(has_admin_cookie) as admin_session_present by clientip, uri_path, http_referer
| where count >= 1
| convert ctime(first_seen) ctime(last_seen)
```

### Microsoft KQL

```kql
AppServiceHTTPLogs
| where TimeGenerated > ago(24h)
| where CsUriStem has "/wp-admin/theme-install.php"
| extend ThemeParam = extract(@"theme=([^&]+)", 1, tostring(CsUriQuery))
| where ThemeParam matches regex @"(?i)(%22|%5d|%3e|%2a)" or ThemeParam matches regex @'[\"\]>*]'
| extend CookiePresent = iif(isnotempty(CsCookie) and CsCookie has "wordpress_logged_in", true, false)
| project TimeGenerated, CIp, CsUriStem, ThemeParam, CookiePresent, CsUserAgent, CsReferer, ScStatus
| summarize FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Count = count(), ThemeParams = make_set(ThemeParam), AdminSessionSeen = max(CookiePresent) by CIp, CsUriStem
| where Count >= 1
```

### Sigma

```yaml
title: WordPress Click2Shell Theme-Slug Selector-Injection Request
id: 7a1e4c2d-9f3b-4e6a-8c1d-2b5f9a7e3c10
status: experimental
description: Detects requests to WordPress core's theme-install.php containing CSS-selector metacharacters in the theme parameter, the core Click2Shell forced-install exploitation primitive that redirects an authenticated admin's programmatic click to an attacker-chosen theme.
references:
    - https://pwn.ai/blog/click2shell
    - https://patchstack.com/articles/click2shell-the-rce-wordpress-7-1-1-just-patched/
    - https://thehackernews.com/2026/09/new-wordpress-click2shell-flaw-forces.html
author: AII-Detector — ThreadLinqs Intelligence
date: 2026-09-21
tags:
    - attack.initial-access
    - attack.t1190
    - attack.execution
    - attack.t1204.001
    - attack.t1566.002
    - cve.2026.click2shell
logsource:
    category: webserver
    product: apache
detection:
    selection_path:
        cs-uri-stem|contains: '/wp-admin/theme-install.php'
    selection_payload:
        cs-uri-query|contains:
            - 'theme=%22%5d%3e%2a'
            - 'theme=%22]>*'
            - '"]>*'
            - '%22%5D%3E'
    condition: selection_path and selection_payload
falsepositives:
    - Automated vulnerability scanners probing theme-install.php with fuzzed parameters (non-authenticated context)
    - Security researcher validation testing against a lab/staging instance
level: high
```

**Known false positives:**

- Automated WordPress vulnerability scanners fuzzing theme-install.php with arbitrary special characters, not chained to an authenticated admin click
- Security research/lab reproduction of the published PoC against a non-production instance

**Tuning notes:** Correlate with the presence of a wordpress_logged_in_* session cookie on the same request to confirm the victim was an authenticated administrator (this is the distinguishing factor from harmless scanner noise); if WAF/CDN logs available, alert only when the payload decodes to CSS-selector metacharacters rather than alerting on every theme= parameter.

### 8 more detection rules (Splunk SPL, Microsoft KQL, Sigma), unlock with TL Creds

- WordPress theme-install.php CSS/jQuery Selector-Injection URL (Click2Shell Forced-Install Primitive) (locked: unlock with TL Creds)
- WordPress Customizer Pre-Activation Load or Unauthenticated wp_ajax Plugin-Installer Call (locked: unlock with TL Creds)
- WordPress Server Egress Fetch of Remote Plugin ZIP Followed by New PHP Web Shell Artifact (Click2Shell RCE Delivery) (locked: unlock with TL Creds)
- WordPress theme-install.php CSS/jQuery Selector-Injection URL (Click2Shell Forced-Install Primitive) (locked: unlock with TL Creds)
- WordPress Customizer Pre-Activation Load or Unauthenticated wp_ajax Plugin-Installer Call (locked: unlock with TL Creds)
- WordPress Server Outbound Plugin ZIP Fetch Followed by New PHP Web Shell Artifact (Click2Shell RCE Delivery) (locked: unlock with TL Creds)
- WordPress Customizer Pre-Activation Load + Unauthenticated AJAX Plugin-Installer Invocation (Mobile Repair Zone Pattern) (locked: unlock with TL Creds)
- WordPress Server Egress Fetch of Remote Plugin ZIP Followed by New PHP Web Shell Artifact (Click2Shell RCE Delivery) (locked: unlock with TL Creds)

Sign up free to unlock the detection rules: https://threadlinqs.com/?modal=signup

## Sources

- [Click2Shell WordPress Flaw](https://gbhackers.com/click2shell-wordpress-flaw/)
- [Preauth WordPress Core Theme Preview Injection to RCE Chain (Click2Shell)](https://pwn.ai/blog/click2shell)
- [New WordPress Click2Shell Flaw Forces Theme Installs, Can Chain to Code Execution](https://thehackernews.com/2026/09/new-wordpress-click2shell-flaw-forces.html)
- [Click2Shell: The RCE WordPress 7.1.1 Just Patched](https://patchstack.com/articles/click2shell-the-rce-wordpress-7-1-1-just-patched/)
- [WordPress 7.1.1 Maintenance and Security Release](https://wordpress.org/news/2026/09/wordpress-7-1-1-maintenance-and-security-release/)
- [WordPress 7.1.1 Fixes 11 Security Flaws Including Stored XSS and Path Traversal](https://gbhackers.com/wordpress-7-1-1-fixes-11-security-flaws/)
- [Mobile Repair Zone WordPress Theme](https://wordpress.org/themes/mobile-repair-zone/)
- [click2shell-poc: PoC scripts for the Click2Shell WordPress pre-auth RCE chain](https://github.com/Usman0220/click2shell-poc)
- [HackfutSecRoot/click2shell -- WordPress Pre-Auth RCE Chain (PoC)](https://github.com/HackfutSecRoot/click2shell)
- [Click2Shell-Sicherheitslücke; zeitnah auf WordPress 7.1.1 aktualisieren](https://borncity.com/blog/en/2026/09/18/click2shell-sicherheitsluecke-dringend-auf-wordpress-7-1-1-aktualsieren/)

## Full data

The other 8 detection rules (Splunk SPL / Microsoft KQL / Sigma) unlock with TL Creds; a free account includes daily creds: https://threadlinqs.com/?modal=signup
Indicator values unlock with TL Creds, at a lower price on Red and Purple; AI agents can query rules and IOCs through the Threadlinqs MCP server (Purple): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-2597
