
Click2Shell: The WordPress Core Theme-Install Flaw Fixed in 7.1.1
Click2Shell lets a crafted link install a WordPress.org theme with no click, and chains to code execution. What it is and how 7.1.1 fixes it.

A logged-in administrator opens a link. Nothing appears to happen. The site looks exactly as it did, the active theme hasn't changed, and no dialog asked to confirm anything. Behind that quiet screen, WordPress has just downloaded and installed a theme the administrator never chose, using the administrator's own session to authorize it. That is Click2Shell, and it is one of the 11 security issues fixed in WordPress 7.1.1 on September 17, 2026.
Click2Shell matters less for what the core bug does on its own and more for what it removes: the requirement that an attacker first get their own code onto your server. The flaw hands them a way to place a real, attacker-chosen theme on disk from the official directory, and a separate weakness in a theme turns that foothold into PHP execution. This article explains how the chain works, what the WordPress patch actually changed, why "installed but inactive" is not the same as safe, and what to do whether or not your site auto-updated.
TL;DR
- Click2Shell is a WordPress core vulnerability fixed in 7.1.1 (September 17, 2026). A specially crafted
theme-install.phplink, opened by a logged-in administrator, makes WordPress install and preview an inactive theme from WordPress.org with no Install or Activate click.- The core bug is a selector-injection issue. The theme slug in the URL is read one way by the WordPress.org API and a different, unsafe way by JavaScript in the admin's browser, which ends up clicking the real Install button on the attacker's behalf.
- On its own it is rated High (CVSS 7.1). Chained to a vulnerable theme it reaches code execution and is rated Critical (CVSS 9.6) by the reporting firm, pwn.ai. WordPress has not published its own severity, and no CVE was assigned at disclosure.
- Updating core to 7.1.1 (or your branch's patched release) closes the demonstrated attack, regardless of which themes your site has installed.
- There is no reported real-world exploitation, and the attack still needs a logged-in administrator to open the link. That is a reason to move quickly, not to relax.
What is Click2Shell?
Click2Shell is the name the security firm pwn.ai gave to an attack chain against WordPress core, disclosed on September 18, 2026, a day after the fix shipped. The name follows a pattern the same researchers set with earlier chains such as XSS2Shell, and it describes the shape of the attack: one click by a logged-in administrator, ending in a shell.
The core vulnerability is narrow and specific. WordPress's theme installer accepts URLs like /wp-admin/theme-install.php?theme=<slug>, which are meant to open the preview for a theme in the WordPress.org directory. The bug is that the value in that URL is interpreted twice, by two different pieces of code that don't agree on what it means. The result is that WordPress's own admin JavaScript can be tricked into clicking the Install button by itself.
WordPress described the issue in its 7.1.1 release notes in deliberately plain terms: "Specially crafted URLs can automatically install and preview an inactive theme from WordPress.org." That sentence is accurate, and it is also where the release notes stop. It does not mention the code-execution continuation that the researchers demonstrated, which is the part that turns an odd installer quirk into something worth an emergency update.
The distinction between the standalone bug and the full chain runs through this whole topic, so it is worth stating once, clearly:
- The standalone core bug lets an unauthenticated attacker force an administrator's site to install a real, attacker-selected theme from the official WordPress.org catalog. It cannot install an arbitrary ZIP of the attacker's own making. pwn.ai rated this High, CVSS 7.1.
- The full chain combines that forced install with a separate flaw in the installed theme to run attacker-supplied PHP on the server. pwn.ai rated this Critical, CVSS 9.6.
How the core bug works
The mechanism is a good example of a whole class of web bugs: the same string treated as data in one place and as code in another.
When you load theme-install.php?theme=<slug>, the admin page sends that slug to the WordPress.org Themes API to fetch the matching theme. The API applies slug canonicalization, which strips the value down to a valid theme slug. So a messy input is reduced to a clean one, and the API returns a genuine theme.
The problem is on the browser side. Inside wp-admin/js/theme.js, once the query succeeds, WordPress took the original slug value, punctuation and all, and dropped it straight into a jQuery selector to find and click the theme's card:
$( 'div[data-slug="' + slug + '"]' ).trigger( 'click' );A selector is code. If the slug contains characters that mean something in selector syntax, they are interpreted as structure rather than as part of a name. Consider a slug value like this:
twentytwenty"]>*>*>*/*The WordPress.org API canonicalizes that back to twentytwenty and returns the genuine Twenty Twenty theme. The browser, though, builds a selector out of the raw text:
div[data-slug="twentytwenty"]>*>*>*/*"]The injected quote closes the attribute match early. The child combinators (>*>*) then walk down into the elements of the returned theme card, and the trailing /* comments out the fragment WordPress appends afterward. Instead of selecting only the card, the selector now reaches the card's action controls, including the genuine Install button. WordPress then runs .trigger( 'click' ) on it.
That is the entire forced-install primitive. Two details make it work without the attacker needing any access of their own:
- The install nonce is already present. The trusted admin page carries its own security token, so the attacker never has to supply one.
- The capability is supplied by the victim. Installing themes requires the
install_themescapability. The logged-in administrator has it, and their session spends it.
The attacker provides neither the token nor the permission. They only provide the shape of the URL. WordPress's own script does the rest.
Installed is not the same as inactive
If the story ended with an inactive theme sitting on disk, Click2Shell would be a low-grade nuisance. An installed-but-not-activated theme sounds dormant. The uncomfortable finding is that it isn't.
WordPress can load a theme's PHP while building a Customizer preview, even when a different theme is the active one. The researchers reached this through a request shaped like:
/wp-admin/admin-ajax.php?wp_customize=on&customize_theme=mobile-repair-zoneThat request causes the inactive theme's functions.php to load, which gives its code a chance to register hooks and AJAX handlers, all while the database still lists your real theme as active. Your site's appearance never changes, which is exactly what makes the whole sequence hard to notice.
The theme pwn.ai demonstrated with, Mobile Repair Zone (on version 2.5.4 at the time), carried a second flaw. When its PHP loaded, it registered an authenticated AJAX action that took an attacker-supplied plugin package URL, downloaded it, unpacked it into the plugins directory, and activated it, with no nonce and no capability check on the request. Chained after the forced install, that handler ran attacker-controlled PHP under the web server's account. The researchers noted that they found similar pre-activation issues in more than 40 themes hosted on WordPress.org, so this was not a single unlucky theme.
Put end to end, one crafted link that an administrator opens can:
- install an official catalog theme automatically;
- load that inactive theme's PHP through the Customizer preview;
- reach the theme's unprotected installer;
- write an attacker-selected package to disk; and
- execute PHP on the server.
At that point the usual consequences of server-side code execution apply: reading wp-config.php and database credentials, creating administrator accounts, altering content and files, and reaching anything else the PHP worker can touch, including WooCommerce and other plugin data.
Important: The theme-side flaw is what elevates Click2Shell from High to Critical, but it is not the part WordPress can patch, because it lives in third-party themes. The core fix in 7.1.1 is the right control point precisely because it removes the forced install that every version of the chain depends on.
What WordPress changed in 7.1.1
The core fix shipped in changeset 63664 and touches one file, wp-admin/js/theme.js. The vulnerable line:
$( 'div[data-slug="' + slug + '"]' ).trigger( 'click' );became:
$( 'div.theme[data-slug="' + $.escapeSelector( slug ) + '"]' ).trigger( 'click' );Two changes, each doing part of the job:
$.escapeSelector( slug )escapes the URL-derived value before it enters selector syntax. The injected quote, combinators, and comment are now treated as literal characters in a slug that doesn't exist, so they match nothing instead of restructuring the query.div.themeconstrains the match to an actual theme card rather than anydivcarrying thatdata-slug, which narrows what the selector can reach even if something slipped through.
Because the fix is entirely in an admin JavaScript file, updating core is all that's required on your side. There is no setting to change and no database migration.
Which sites and versions are affected
According to the WordPress 7.1.1 documentation, the crafted-URL theme issue affects releases from version 6.0 up through the versions immediately before the fix. The researchers reproduced it on WordPress 7.0.4, and the WordPress security team reproduced it on 7.1.0. As with the other fixes in this release, the patch was backported to every branch still receiving security updates, back to 4.7.
If you're on the current branch, the fix is in 7.1.1. If you're on an older branch, the same-day patched releases apply.
| If you're on | Update to at least |
|---|---|
| 7.1 | 7.1.1 |
| 7.0 | 7.0.5 |
| 6.9 | 6.9.8 |
| 6.8 | 6.8.9 |
| 6.7 | 6.7.8 |
| 6.6 | 6.6.8 |
| 6.5 | 6.5.11 |
| 6.0 | 6.0.15 |
| 5.9 – 4.7 | The patched release for your branch |
| 4.6 or older | No fix. Move to a supported version. |
Only the most recent release is actively supported. Backports are a courtesy, so treat a backported patch as time to plan the move to 7.1.1, not a permanent home. Our full breakdown of the release, covering all 11 fixes and the per-branch versions, is in WordPress 7.1.1 Is a Security Release.
A note on CVE and on the theme's status
Two things about Click2Shell are still moving, and it's better to name them than to guess:
- No CVE identifier had been assigned when the fix and disclosure went public. pwn.ai says WordPress plans to assign one. If you track vulnerabilities by CVE, expect the number to appear later and don't assume its absence means the issue isn't real.
- The theme side is version-dependent. The demonstrated theme flaw was in Mobile Repair Zone 2.5.4, and similar patterns exist in dozens of other themes. Whether any given theme has since removed its unprotected handler is something to verify against that theme's own current version, not something to assume. This is another reason the core patch is the fix that matters: it holds regardless of what any individual theme does or doesn't fix.
Is your site actually patched?
WordPress installs minor releases like 7.1.1 automatically by default, so most sites updated within hours. "Most" is not "all," and the sites that don't auto-update are often the ones whose owners are surest they did. Confirm the version rather than assuming it.
From the dashboard, Tools > Site Health reports whether background updates can run and, if not, why. From the command line:
# What version is actually running?
wp core version
# Common reasons a site silently stays behind.
# An "not defined" error means the default applies.
wp config get WP_AUTO_UPDATE_CORE
wp config get AUTOMATIC_UPDATER_DISABLED
wp config get DISALLOW_FILE_MODS
# Is WordPress inside a version-control checkout? (run from the WP root)
git rev-parse --show-toplevel 2>/dev/null || echo "Not inside a Git checkout"A Git or Composer-managed core, DISALLOW_FILE_MODS, disabled WP-Cron, or file-permission problems can all stop background updates without any warning. If wp core version doesn't report 7.1.1 (or your branch's patched release), update manually.
If you run several sites, WP-CLI aliases make this a single audit. With aliases defined in wp-cli.yml, wp @all core version prints the version of every site at once.
What to do now
For most sites this is a single update and a few minutes of checking. The steps around the update are what make it safe.
Back up first. A minor release rarely breaks anything, but a restore point taken minutes before the change is the one you'll want if it does. On MagicWP you can trigger an on-demand backup before any change, on top of the daily off-site backups.
Update core. Use Dashboard > Updates > Update Now, or WP-CLI:
# Update to the latest release in your current branch only wp core update --minor # Then run the database updater (a no-op if nothing changed) wp core update-dbThe
--minorflag keeps an older branch on its own backport. Drop it when you're ready to move to the latest major version.Verify core files against the official release. After any security update, confirm the files on disk match what WordPress shipped. This also surfaces leftover modified core files from an earlier compromise:
wp core verify-checksumsInvestigate anything reported as modified or unexpected in core directories rather than ignoring it.
Review your installed themes. Because the core bug's outcome is an unexpected theme appearing on disk, list what's installed and look for anything you didn't add. An inactive theme you don't recognize is worth removing:
# List every installed theme and its status wp theme list # Delete a theme you didn't install (only after confirming it's not a parent # of your active theme or a fallback you want to keep) wp theme delete <theme-slug>Deleting unused themes is good general hygiene here: a theme that isn't on disk can't be loaded through a Customizer preview.
Be realistic about detection. No public technical signature exists for confirming whether a specific site was targeted before it was patched, and Click2Shell has no reported in-the-wild exploitation. Checksum verification and a theme review catch the obvious cases; they are not proof that nothing happened. If you find an unexplained admin user, an unfamiliar plugin, or modified core files, treat it as a potential compromise and work from a known-clean backup.
Administrator link hygiene
Click2Shell needs a logged-in administrator to open the attacker's link, which points at a habit worth reinforcing regardless of this specific bug. A surprising number of admin-only WordPress attacks, including XSS2Shell before this one, come down to an administrator following a link while logged in to wp-admin.
- Don't open unexpected links to your own admin area, especially ones with long encoded query strings, while logged in.
- Keep separate accounts for administration and for daily browsing where practical, so a stray click in a general-purpose session isn't happening inside an admin login.
- Log out of wp-admin when you're done, rather than leaving an authenticated session open indefinitely.
- Keep the number of true administrator accounts small. Fewer administrators means fewer sessions that can be turned against the site.
None of this replaces the update. The patched code closes the demonstrated attack; link hygiene reduces exposure to the next admin-triggered bug that hasn't been found yet.
Frequently Asked Questions
What is Click2Shell in WordPress?
Click2Shell is a WordPress core vulnerability fixed in version 7.1.1 on September 17, 2026, and disclosed by the security firm pwn.ai. A specially crafted theme-install.php URL, opened by a logged-in administrator, causes WordPress to automatically install and preview an inactive theme from the WordPress.org directory without any Install or Activate click. Chained with a separate flaw in the installed theme, it was demonstrated reaching PHP code execution on the server.
Does Click2Shell have a CVE number?
No CVE identifier had been assigned when the fix shipped and the vulnerability was disclosed. pwn.ai has stated that WordPress plans to assign one. If you track vulnerabilities by CVE, expect the identifier to appear after the fact; its absence at disclosure does not mean the issue is minor.
How severe is Click2Shell?
The reporting firm rated the standalone forced-install bug as High (CVSS 7.1) and the full chain to code execution as Critical (CVSS 9.6). WordPress has not published a severity rating of its own and described the issue narrowly in its release notes. Because the chain can end in server-side code execution, sites should treat updating as urgent even though there is no reported exploitation.
Has Click2Shell been exploited in the wild?
There is no reported real-world exploitation of Click2Shell as of its disclosure. That distinguishes it from wp2shell, a separate July 2026 WordPress core chain that was exploited in the wild and required no login. Click2Shell still needs a logged-in administrator to open the attacker's link, which raises the bar but does not remove the risk. Update promptly rather than waiting for exploitation to appear.
Do I need to do anything if my site auto-updated?
Confirm that it happened. Minor releases install automatically by default, so most sites updated on their own, but a Git checkout, Composer-managed core, DISALLOW_FILE_MODS, disabled WP-Cron, or file-permission problems can stop background updates silently. Run wp core version or check Dashboard > Updates. If it doesn't show 7.1.1 or your branch's patched release, update manually.
Should I delete the Mobile Repair Zone theme?
If the theme is installed and you don't use it, removing unused themes is sound general hygiene, because a theme that isn't on disk can't be loaded through a Customizer preview. The more important action is updating WordPress core to 7.1.1, which removes the forced-install step the whole attack depends on, regardless of which themes are present. Whether any particular theme has since fixed its own handler should be checked against that theme's current version, not assumed.
Which WordPress versions are affected by Click2Shell?
According to the WordPress 7.1.1 documentation, the crafted-URL theme issue affects releases from version 6.0 up to the versions just before the fix. The researchers reproduced it on 7.0.4 and the WordPress security team on 7.1.0. Fixes were backported to every branch still receiving security updates, back to 4.7, so 7.0 sites should be on 7.0.5, 6.9 on 6.9.8, and so on.
Is a firewall enough to protect against Click2Shell until I update?
A web application firewall may block some known request patterns, but it should not be treated as a substitute for the patch. Firewall rules target specific payloads; the fixed code removes the flaw itself. Update core as the primary control, and rely on a firewall only as a temporary, partial measure if an update is genuinely blocked for a short window.
Conclusion
Click2Shell is a reminder that "installed but not active" is not a safety boundary in WordPress, and that a bug in how the admin interface reads a URL can be enough to place attacker-chosen code on a server. The core fix in WordPress 7.1.1 is small and self-contained: it escapes and constrains a selector so a crafted theme slug can no longer make the browser click Install on its own. Because that fix removes the forced install the entire chain relies on, updating core closes the demonstrated attack whatever themes your site happens to carry.
The practical response is the same one every recent core security release has called for. Update to 7.1.1 or your branch's patched version, confirm the version instead of assuming the update ran, verify your core files, and take a look at what themes are installed. Automatic core updates with rollback, daily off-site backups, and one-click staging are part of MagicWP's managed security, which is what turns a release like this into a routine event rather than a scramble. Wherever your sites run, the goal is an update path boring enough that a fix for the next Click2Shell reaches them before anyone has to think about it.
Get the best of MagicWP in your inbox.
Monthly engineering notes, product updates, and WordPress performance tips. No spam, unsubscribe anytime.

