WordPress Click2Shell: the forced theme install still needs an administrator to open the link
WordPress shipped the Click2Shell fix in 25 branch releases on 17 September 2026, and 24 of them carry it. The flaw plants a real catalogue theme without anyone pressing Install, but only inside a signed-in administrator's own browser.
By Parminder Kumar Sharma · · 21 min read

Twenty-four branches carry the fix. One does not.
On 17 September 2026 WordPress published 25 releases in one go: 7.1.1, and a backport for every older branch still eligible for security fixes, down to 4.7.36. I opened the security list on all 25 of them. The line that describes Click2Shell, worded identically everywhere as an issue allowing a crafted URL to install and preview a theme from WordPress.org, reported by Paulos Yibelo and pwn.ai, appears in 24 of those 25 releases. It is missing from exactly one: 4.7.36.
That is a countable fact rather than a summary of the news, and it settles a point the coverage got wrong. The Hacker News told readers that WordPress's notes confirm the flaw "from version 6.0 up through the releases just before the fix". They do not. The 7.1.1 page gives only a per-branch tally, of the form that a branch is affected by 10 of the 11 vulnerabilities, and never says which 10. The individual branch pages do name them, and they put this one in 4.8.31, a dozen major versions below the floor the coverage reported.
Where the Click2Shell fix landed, read from each branch release note on wordpress.org on 19 September 2026. The third column is WordPress's own count of how many of the eleven 7.1.1 security fixes that branch received.
| Branch | Release carrying the theme install fix | Security fixes in that release |
|---|---|---|
| 7.1 | 7.1.1 | 11 of 11 |
| 7.0, 6.9, 6.8, 6.7 | 7.0.5, 6.9.8, 6.8.9, 6.7.8 | 11 of 11 |
| 6.6 down to 5.9 | 6.6.8 down to 5.9.17 | 10 of 11 |
| 5.8, 5.7, 5.6 | 5.8.16, 5.7.18, 5.6.20 | 9 of 11 |
| 5.5, 5.4, 5.3 | 5.5.21, 5.4.22, 5.3.24 | 8 of 11 |
| 5.2 down to 4.8 | 5.2.27 down to 4.8.31 | 7 of 11 |
| 4.7 | 4.7.36 does not list this issue | 6 of 11 |
| 4.6 and earlier | No security updates at all | Not stated |
What that does not establish is that 4.7 is safe. WordPress does not say why the line is absent there. The obvious reading, that the vulnerable code had not yet been written in 4.7, is my inference and not a vendor statement, and the same page reminds readers that only the most recent version of WordPress is actively supported, so a 4.7 site is carrying far more than this one issue. Nor does the ladder say anything about whether any particular site was attacked. It tells you what to patch, and nothing else.
What the name promises, and what the attack actually needs
Two names are doing work in this story, and both shade the preconditions in the attacker's favour.
The first is the framing that WordPress forces theme installs. Forced, in ordinary security usage, means the defender does nothing at all. That is not what happens. WordPress's own one-line description is careful about it: "Specially crafted URLs can automatically install and preview an inactive theme from WordPress.org." Somebody has to open the URL, and that somebody has to be holding a WordPress session that carries the install_themes capability. What is automatic is the press of the Install button, not the arrival at the page.
The second is pwn.ai's own title, which calls this a preauth WordPress core theme preview injection to remote code execution chain. Pre-authentication describes the attacker, who genuinely needs no WordPress account of any kind, not even a subscriber. It does not describe the victim. pwn.ai's own severity vector concedes the point in the same paragraph: it scores the full chain with UI:R, meaning user interaction required, and says that is what lowers the score. Its published demonstration opens a popup, shows the target the ordinary WordPress login screen if they are not already signed in, and then waits sixty seconds before firing the second stage. A chain that budgets a minute for you to type your password is not a chain that runs without you.
How the shorthand compares with what the primary sources require. Drawn from the WordPress 7.1.1 release note and the pwn.ai write-up.
| The shorthand | What the sources actually require |
|---|---|
| Forces theme installs | WordPress's own JavaScript presses the genuine Install control, after an administrator opens the attacker's link in a browser already holding their session |
| Pre-authentication | True of the attacker, who needs no WordPress account. False of the victim, who must be signed in as an administrator, or sign in when WordPress prompts |
| No user interaction | Not claimed by anyone. pwn.ai scores the chain with user interaction required, and WordPress says specially crafted URLs, which someone has to open |
| Arbitrary theme installed | Not stated. pwn.ai writes that the core bug "does not accept an arbitrary theme ZIP by itself". It installs a current package from the official catalogue |
| Any WordPress site | On Multisite, `install_themes` belongs only to the Super Admin, not to a site administrator, so an ordinary site admin's session will not install a theme |
None of that makes the flaw unimportant. It makes it a cross-site request forgery pattern against a privileged session, which is a category most UK small organisations are badly placed to resist, for reasons the last part of this briefing sets out. But defenders who plan on the basis of "forces theme installs" will reach for the wrong controls. Nothing at your perimeter sees this. The request that installs the theme comes from an authorised browser, carries a valid cookie and a valid nonce, and is served by your own admin screen.
One value, two readings
WordPress's theme installer accepts a route of the form /wp-admin/theme-install.php?theme=SLUG. The value is meant to name a theme in the WordPress.org catalogue, so the page can fetch that theme's record and open its preview.
That single value then crossed two consumers that did not agree on what it meant. On the server side, the WordPress.org Themes API applied slug canonicalisation, stripped the punctuation an attacker had added, and returned the genuine catalogue entry for the real theme underneath. In the administrator's browser, wp-admin/js/theme.js took the original value, punctuation intact, and concatenated it into a jQuery attribute selector so that it could find the matching theme card on the page and trigger a click on it.
One quote character closes the attribute selector early. Child combinators then walk from the theme card down into its action controls, and a trailing CSS comment neutralises the fragment WordPress appends afterwards. The selector that was supposed to match a card instead matches the Install button inside it, and the next line of WordPress's own code calls trigger with a click event. That is the whole primitive. I am not reproducing the crafted value; it is published and it is trivial, and the mechanism above is what a defender needs.
The attacker supplies neither the installation nonce nor the capability. The trusted admin page already has the nonce, and the signed-in administrator already has install_themes. pwn.ai's phrasing is the clearest line in the write-up: WordPress's own JavaScript "spends both on the attacker's behalf".
The fix WordPress shipped is small and sits exactly where the confusion was. According to pwn.ai, changeset 63664 constrains the match to a real theme card and escapes the URL derived value before it becomes selector syntax:
$( 'div.theme[data-slug="' + $.escapeSelector( slug ) + '"]' ).trigger( 'click' );
After that change, the injected quote, the combinators and the comment are treated as literal characters in a slug that matches nothing, so the selector no longer walks into the Install control. Note what the patch does not do: it does not add a confirmation step, and it does not change what an installed theme is allowed to do. It closes one parser disagreement.
Installed is not active, and not inert
A forced install of a real, inactive catalogue theme is a nuisance on its own. Your site's appearance does not change, because the theme is never switched on. That is also the reason it is worth worrying about: nothing on the site looks wrong.
The step that turns it into code execution is that an inactive theme is not dormant. WordPress can load a theme's PHP while preparing a Customizer preview, through an admin-ajax request carrying wp_customize=on and a customize_theme value, even while the database still names a different theme as active. That gives the freshly installed theme a chance to register its hooks and handlers.
pwn.ai chained this with a separate flaw in the WordPress.org package for Mobile Repair Zone 2.5.4. That theme registered a handler on an authenticated Ajax action, took a plugin package URL out of the request, fetched it, unpacked it into the plugins directory and loaded the entry point. The vulnerable path checked neither an action nonce nor whether the current user was allowed to install plugins. Its only access control was the one the hook gives you for free, and WordPress's own reference for that hook is explicit that it "only fires for logged-in users", which is a very long way from administrators only.
Two things about that theme are worth putting on the record, because they cut in opposite directions.
First, its installed base is irrelevant. The WordPress.org listing for Mobile Repair Zone shows 40 or more active installations, which is close to nothing. It does not matter, because the point of the chain is that the attacker installs it on your site. A theme nobody uses is as good a weapon as a popular one, and better, because nobody is watching it.
Second, the listing now shows version 2.5.5, last updated on 9 September 2026, eight days before WordPress shipped 7.1.1 and nine days before pwn.ai published. Neither WordPress nor pwn.ai states whether 2.5.5 fixes the handler, and I could not establish it from the theme directory page alone. Treat that as not stated. pwn.ai further claims it found the same pre-activation pattern in over 40 third party themes hosted on WordPress.org, and names none of them, so that claim is not checkable from the published material either.
All of which is the honest shape of the chain: the core fix in 7.1.1 removes the delivery mechanism for every theme at once, which is why updating core is the action that matters, rather than hunting for individual bad themes you do not yet have.
What fixes it, and whether it fixes itself
The right target depends on which branch you are on. A site on 7.1 goes to 7.1.1. A site on 6.8 goes to 6.8.9 and is fixed, without jumping to 7.1. That matters for anyone running a theme or plugin estate that is pinned to an older branch, because the security answer does not require a major upgrade.
Automatic updates will do this for most sites, with real caveats. WordPress has shipped automatic background updates since 3.7, and minor core updates, which its documentation defines as exactly "maintenance and security releases", are enabled by default. 7.1.0 to 7.1.1 is a minor release, so a default installation picks it up on its own. The documentation is equally clear about how that gets turned off: an AUTOMATIC_UPDATER_DISABLED constant, a WP_AUTO_UPDATE_CORE value of false, a filter in a plugin, or WordPress detecting a version control checkout. Managed hosting control panels add their own switch on top. None of those failure modes announce themselves, which is why the instruction is to check the reported version rather than to assume.
What WordPress states about this issue, and what it leaves open. Compiled from the 7.1.1 release announcement, the 7.1.1 and per-branch release notes, and the WordPress automatic updates documentation.
| Question | Stated on the record | Not stated |
|---|---|---|
| Which branches are fixed | 4.8 through 7.1, named individually in each branch release note | Whether 4.7 and earlier contain the vulnerable code at all |
| Severity | Nothing. WordPress published no rating of its own | Any vendor CVSS score, vector or severity label |
| Exploitation | pwn.ai and the news coverage both say no sign of real attacks | Any WordPress statement about exploitation, either way |
| Workaround | None offered by WordPress or by pwn.ai | Whether any configuration change blocks the forced install short of updating |
| Automatic updates | Minor core updates are on by default and this is a minor release | Whether any given site has them switched off by a host, a constant or a filter |
One structural mitigation is worth knowing because it is already true on some estates. On a single site installation, install_themes belongs to the Administrator. On Multisite, WordPress's roles and capabilities documentation puts install_themes with the Super Admin only. A site administrator on a Multisite network therefore does not hold the capability the forced install spends, so their session is not the one an attacker wants. That is not a control you can switch on this afternoon, but it is a reason a Multisite estate is in a better position than a field of standalone sites, and it is a point in favour of the architecture next time somebody asks.
The paperwork does not match the risk, in both directions
If you track vulnerabilities by CVE, Click2Shell is invisible. I queried the National Vulnerability Database for the 7.1.1 release on 19 September 2026. Exactly one CVE exists for that release: CVE-2026-93485, assigned by Patchstack, published 18 September, scored 7.1 High, and covering the unauthenticated stored cross-site scripting issue in paragraph formatting reported by Rafie Muhammad. That is a different bug. Ten of the eleven fixes in 7.1.1, including this one, had no CVE at all.
The coincidence of numbers is worth flagging so nobody merges them: pwn.ai also scored the standalone forced install at 7.1. Those two 7.1 scores describe unrelated issues from the same release.
The scores themselves disagree across sources, and the disagreement is not trivial. pwn.ai's write-up assesses the standalone primitive as High, CVSS 3.1 7.1, and the demonstrated chain as Critical, CVSS 3.1 9.3, explicitly noting that user interaction required is what pulls it down. The Hacker News reported the chain at 9.6. The pwn.ai post says 9.3. Where a secondary source and the primary research differ, the primary research is the one to quote, and 9.3 is the number on the record.
Who has said what about Click2Shell's severity and status, checked on 19 September 2026 against NVD, the CISA Known Exploited Vulnerabilities catalogue and the published write-ups.
| Source | On the record | What it does not give you |
|---|---|---|
| pwn.ai | High, CVSS 3.1 7.1 standalone. Critical, CVSS 3.1 9.3 for the chain, with user interaction required | The full vector strings, and any independent verification of the scores |
| WordPress | One sentence in the security list, plus the file and branch record | No severity, no CVE at the time of writing, no exploitation statement |
| NVD | One CVE for the whole 7.1.1 release, CVE-2026-93485, for a different issue | Any identifier a defender could use to track Click2Shell |
| CISA KEV | Catalogue version 2026.09.18, 1,716 entries, no matching record | Any evidence either way about exploitation in the wild |
| The Hacker News | Reported 9.6 for the chain and a version 6.0 floor | Agreement with the primary sources on either figure |
For scale, compare it with the WordPress core flaw that actually is being exploited. CISA added two WordPress core issues to its Known Exploited Vulnerabilities catalogue on 21 July 2026: CVE-2026-63030, a REST API route confusion, and CVE-2026-60137, a SQL injection in a WP_Query parameter, chained together for unauthenticated remote code execution. CISA gave the first a remediation due date of 24 July 2026, three days after listing, and marked it as requiring forensic triage. Click2Shell is not in that catalogue, has no CVE, and nobody has reported it used in an attack. Those are different risk objects and they deserve different handling. A defender who treats Click2Shell as an emergency on a par with the July chain is spending credibility they will need later.
A word on where the writing comes from. pwn.ai is a penetration testing firm whose own site advertises autonomous offence and lab scores; it named this chain, scored it itself, and published full technical detail with working proof of concept code the day after the fix shipped. Nothing about that is improper, and the method it describes is checkable, which is more than most marketing research offers. It is still marketing, and the name is the marketing. Separately, pwn.ai states that WordPress paid its maximum bug bounty, and puts that maximum at 300 dollars. I could not verify the bounty range: the WordPress HackerOne programme page does not render its bounty table to a plain fetch. If that figure is right, it is its own small comment on how the economics of this ecosystem work.
Why this lands harder on UK small organisations
Start with the exposure, and correct one number while we are here. pwn.ai's post says WordPress "powers 43% of the web, representing an estimated 500 million websites". W3Techs, reading on 19 September 2026, puts WordPress at 40.2 percent of all websites and 58.8 percent of sites whose content management system is known. Forty per cent is an enormous number and the argument does not need rounding up.
The version spread from the same source is more useful than the headline. WordPress 7 accounts for 62.1 percent of WordPress sites, version 6 for 30.9 percent, version 5 for 4.9 percent, version 4 for 2.0 percent and version 3 for 0.2 percent. Adding the last three gives 7.1 percent of all WordPress sites running version 5 or older. Applied to the 40.2 percent figure, that is roughly 2.9 percent of every website on the internet sitting on a WordPress branch old enough that the fix arrived, if it arrived, as a backport somebody had to accept.
Now the UK end of it. The Cyber Security Breaches Survey 2025 to 2026, published by DSIT on 30 April 2026 from a random probability survey of 2,112 UK businesses and 1,085 UK registered charities, gives three numbers that describe this attack almost exactly.
UK figures from the Cyber Security Breaches Survey 2025 to 2026, DSIT, published 30 April 2026. Bases: 2,112 businesses, 1,085 charities.
| Measure | Businesses | Charities |
|---|---|---|
| Phishing, meaning fraudulent emails or being directed to fraudulent websites, as the most common attack type experienced | 38% | 25% |
| Have a policy to apply software security updates within 14 days | 34% | 20% |
| Restrict IT admin and access rights to specific users | 73% | 65% |
Read those three rows together and you have the whole threat model. The delivery method Click2Shell needs is the single most common thing that already happens to UK organisations. The control that stops it, patching quickly, is one of the two least common controls on the survey's entire list, held by a third of businesses and a fifth of charities. And a quarter of businesses and a third of charities do not restrict admin and access rights to specific users, which in a small charity usually means the one person who runs the website is also the person who opens the post, the invoices and the inbox, in one browser profile, all day.
That is precisely the population where a WordPress administrator session sits open in the same browser that receives supplier emails and donation enquiries. The NCSC's guidance for small and medium organisations is unambiguous about the shape of the fix, if not about how easy it is: staff who need an admin account should "have an additional admin account created", should "only use their admin account to perform administrative activities", and should "use their normal work account for day-to-day activities". Click2Shell is a very clean illustration of why that separation is about more than password hygiene. The separation is not protecting the password. It is making sure the browser that opens a stranger's link is not the browser holding a capability that installs code.
What to do, in order
Take this with you
Click2Shell response, in the order worth doing it
- Check the version every WordPress site actually reports, rather than the version you believe it runs. On the dashboard it is At a Glance, or the footer of any admin screen.
- Update core to 7.1.1, or to the fixed release for whichever branch you are on: 7.0.5, 6.9.8, 6.8.9, 6.7.8, 6.6.8, 6.5.11 and so on down to 4.8.31. A branch update is enough; you do not need a major version jump to be fixed.
- If a site reports 4.7.x or older, treat that as a separate and larger problem. WordPress states that only the most recent version is actively supported, and 4.6 and earlier receive no security updates at all.
- Confirm automatic background updates are actually on. Look for AUTOMATIC_UPDATER_DISABLED or WP_AUTO_UPDATE_CORE in wp-config.php, for a plugin filter that disables them, and for a host control panel switch. Site Health flags most of these.
- Open Appearance then Themes on every site and read the list. You are looking for a theme nobody chose, installed but not active. Compare against your own record of what should be there, not against what looks plausible.
- Check the themes directory on disk for folders created since roughly mid August 2026, which is when the flaw was first reported privately. A file modification time is harder to fake casually than a dashboard listing.
- Review the user list for administrator accounts you did not create, and check the registered date column on each.
- Review scheduled tasks. Any cron entry you cannot trace to a plugin or theme you deliberately installed deserves an explanation before you delete it.
- Review the plugins directory the same way, because the demonstrated chain ends by writing a plugin package, not a theme.
- Separate the browsing. Give whoever administers the site a browser profile, or better a separate account or device, that is used for WordPress administration and nothing else, and do not read email or open links in it.
- If you find anything unexplained, preserve it before you clean it. Copy the file listing with timestamps, the user list and the scheduled task list, and take a database backup, before deleting anything.
The question that exposes the gap
The core fix is a one line change to a selector, and it is right. But look at what the chain actually relied on, and ask the harder question.
WordPress treats installing a theme as an ordinary administrative action, protected by a capability and a nonce, and then loads that theme's PHP during a preview before anyone has activated it. As pwn.ai puts it, theme installation is a code deployment operation. Escaping the slug stops one route to the Install button. It does not change the fact that any theme placed on disk can execute before it is ever switched on, and that the ecosystem contains an unknown number of theme packages whose handlers check nothing at all.
So the question for the next release, and for anyone running WordPress at scale in the UK: if an inactive theme can run PHP, what exactly is the word "inactive" protecting you from, and which of your controls were quietly built on the assumption that it protects you from something?
Key facts
Sources
- PrimaryClick2Shell technical write-up: the selector injection, the Customizer preview bridge, the Mobile Repair Zone handler, the disclosure timeline and the researcher CVSS scorespwn.aiaccessed 2026-09-19
- PrimaryWordPress 7.1.1 Maintenance and Security Release: the 11 security fixes, the credit line for this issue, and the backport policyWordPress.orgaccessed 2026-09-19
- PrimaryVersion 7.1.1 release notes: the per-branch affected counts, the list of files revised, and the full security listWordPress.orgaccessed 2026-09-19
- PrimaryVersion 4.8.31 release notes: the oldest branch whose security list names the crafted theme install URL issueWordPress.orgaccessed 2026-09-19
- PrimaryVersion 4.7.36 release notes: the only supported branch whose security list omits the crafted theme install URL issueWordPress.orgaccessed 2026-09-19
- PrimaryVersion 6.8.9 release notes, used to confirm that the backports shipped on the same day as 7.1.1WordPress.orgaccessed 2026-09-19
- PrimaryCVE-2026-93485, the only CVE published for the WordPress 7.1.1 release as of 19 September 2026, covering a different issueNIST National Vulnerability Databaseaccessed 2026-09-19
- PrimaryCVE-2026-63030, the WordPress core interpretation conflict used for the wp2shell comparisonNIST National Vulnerability Databaseaccessed 2026-09-19
- PrimaryKnown Exploited Vulnerabilities catalogue, checked for any Click2Shell or WordPress theme install entryCISAaccessed 2026-09-19
- PrimaryWordPress nonce documentation, used for what a nonce does and does not protectWordPress Developer Resourcesaccessed 2026-09-19
- PrimaryThe authenticated Ajax action hook, used to establish that the theme handler fired for any signed-in userWordPress Developer Resourcesaccessed 2026-09-19
- PrimaryRoles and Capabilities, used for who holds install_themes on single site and on MultisiteWordPress.orgaccessed 2026-09-19
- PrimaryConfiguring Automatic Background Updates, used for whether a default site receives this fix on its ownWordPress Developer Resourcesaccessed 2026-09-19
- PrimaryThe Mobile Repair Zone theme listing, used for the current version, update date and active install countWordPress.orgaccessed 2026-09-19
- PrimaryWordPress usage and version share, used to check the 43 percent claim and to compute the share still on version 5 or olderW3Techsaccessed 2026-09-19
- PrimaryCyber Security Breaches Survey 2025 to 2026, used for UK phishing prevalence, patching policy and admin rights figuresDepartment for Science, Innovation and Technologyaccessed 2026-09-19
- PrimaryProtecting your admin accounts, used for the UK guidance on separating admin and day to day accountsNational Cyber Security Centreaccessed 2026-09-19
- Reported byNews coverage that first carried the story, used as the pointer to the primary sources and as the source of the 9.6 and version 6.0 claims this briefing checksThe Hacker Newsaccessed 2026-09-19


