Click2Shell: One Admin Click Runs PHP on Any WordPress Before 7.1.1
TL;DR what: A parser differential in WordPress Core theme-preview handling, named Click2Shell, lets a crafted URL drive the admin dashboard's own JavaScript into installing attacker-controlled PHP. impact: One click
TL;DR
- what: A parser differential in WordPress Core theme-preview handling, named Click2Shell, lets a crafted URL drive the admin dashboard's own JavaScript into installing attacker-controlled PHP.
- impact: One click by a logged-in administrator writes a webshell into wp-content and executes it as the web server user, with wp-config.php database credentials in reach.
- fix: Update WordPress Core to 7.1.1 and set DISALLOW_FILE_MODS in wp-config.php to disable theme and plugin installation through the web interface.
- who: Every site running WordPress Core 7.1.0 or earlier, with the sharpest exposure on agency and managed-hosting fleets where one browser holds live admin sessions for many sites.
A logged-in WordPress administrator clicking one link is enough to execute attacker-supplied PHP on the server. The bug, called Click2Shell by Paulos Yibelo of pwn.ai, who reported it, affects WordPress Core 7.1.0 and everything before it. WordPress fixed it in 7.1.1, released in September 2026. Complete technical detail and a proof of concept are already public, which means the gap between disclosure and mass scanning is measured in days, not weeks.
One value, two parsers
The root cause is a parser differential. A value carried in a WordPress theme-preview URL is interpreted once by the WordPress.org Themes API and a second time, by different and buggy logic, by JavaScript running in the administrator's browser. The two readings disagree. The server side treats the value as an ordinary theme identifier. The client side, handling the same string through jQuery selectors, resolves it into markup and behavior the server never intended.
That disagreement is the whole exploit. An attacker does not need an account, a token, or a foothold on the host. They need an administrator session to exist in a browser and that browser to load a URL of the attacker's choosing. Everything after that runs with the privileges WordPress already grants an administrator, and an administrator can install themes. A theme is PHP. Installing one is remote code execution with extra steps.
That also explains why WordPress's nonce system does not stop it. Nonces defend against a foreign page forging a request, because the foreign page cannot read the token. Here the request is assembled by WordPress's own admin JavaScript, inside the admin origin, with the nonce already present in the page. The token is supplied correctly. The forgery happens one layer up, in what the JavaScript was persuaded to build.
Why this is not a normal CSRF
Cross-site request forgery is usually rated a moderate problem because the damage ceiling is whatever the victim's role permits, and most roles permit very little. WordPress administrators are the exception. The administrator role owns file modification, and the theme and plugin installers write PHP into the webroot by design. Click2Shell chains a CSRF into that installer, so the outcome is not a changed setting or a deleted post. It is a webshell under wp-content, running as the PHP-FPM or Apache user, with database credentials sitting in wp-config.php one directory up.
The report reached WordPress on August 22, 2026, and the fix landed roughly two weeks later in 7.1.1. That is a fast turnaround by any measure, but the disclosure shipped with a working proof of concept, so every unpatched site now faces copy-and-paste exploitation rather than original research.
The precondition is a person, not a port — Click2Shell cannot be fired at a site from the outside with no human involved. It needs an administrator with a live session to open a crafted URL. Treat that as a weak defense. Administrator sessions survive for weeks in real deployments, agency staff manage dozens of sites from one browser profile, and a link in a support ticket or a contact form reply is all the delivery this requires.
Blast radius
- Every WordPress install running 7.1.0 or earlier, which is the default state of any site without unattended core updates enabled.
- Managed hosting and agency fleets, where one browser profile with live admin sessions can be walked across hundreds of tenants in a single visit.
- Any site where the PHP worker can write to wp-content, which is the standard configuration, not a hardening failure.
- Sites behind a WAF, because the request originates from the administrator's own authenticated browser and reads as normal admin traffic.
What to run today
Two actions close this. Update core to 7.1.1, and set DISALLOW_FILE_MODS in wp-config.php so the theme and plugin installers are disabled entirely. The second control is the one worth keeping after the patch. Most production WordPress sites have no business installing code through the web interface, and turning that capability off removes an entire class of one-click escalation, not just this one.
wp core version --path=/var/www/html
wp core update --version=7.1.1 --path=/var/www/html
wp config set DISALLOW_FILE_MODS true --raw --path=/var/www/html
wp theme list --path=/var/www/html
If you manage a fleet, iterate the webroots rather than trusting an inventory. The version string lives in wp-includes/version.php as $wp_version, and grepping it across every vhost is faster and more accurate than reconciling a spreadsheet.
Assume some sites were already hit
The exploit leaves artifacts. A successful run installs a theme, which means a new directory under wp-content/themes holding PHP that no one on your team wrote, with a modification time after August 22, 2026. Check the options table for recently changed theme values, and check your web server access log for POST requests to /wp-admin/update.php carrying action=install-theme or upload-theme with an external Referer. Legitimate theme installs start from a click inside the admin dashboard, so the Referer is your own host.
⚠️ A patch does not evict a shell — Updating to 7.1.1 stops the exploit, it does not remove code an attacker already wrote to disk. If you find an unexplained theme directory or a PHP file with a recent mtime in the webroot, rotate the database credentials in wp-config.php, rotate every administrator password and force session invalidation, then audit for new users and scheduled tasks created after August 22, 2026.
The pattern to watch for
Click2Shell is a parser differential, and that bug class is having a long run. The same shape shows up in request smuggling, in URL validation bypasses that become SSRF, and in every case where two components in a chain each implement their own reading of the same untrusted string. WordPress is fertile ground for it because the platform deliberately blurs the line between configuration and code. Any product where a privileged user can write executable files through a web form carries the same impact ceiling, and the only durable fix is to take that capability away in production.
Originally published on RedEye Threat Intelligence.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.