Start trial

Click2Shell: The RCE WordPress 7.1.1 Just Patched

WordPress 7.1.1 patched a vulnerability reported by pwn.ai’s Paulos Yibelo named Click2Shell, a complicated vulnerability chaining Cross-Site Request Forgery (C

PublishedSeptember 18, 2026
Chazz Wolcott avatar
Chazz Wolcott
Security Researcher at Patchstack

WordPress 7.1.1 patched a vulnerability reported by pwn.ai’s Paulos Yibelo named Click2Shell, a complicated vulnerability chaining Cross-Site Request Forgery (CSRF) into selector injection to turn a single click into a remote shell. It was reported responsibly and was fixed in the 17 September release; it’s also an interesting vulnerability which highlights the power of chaining different weaknesses to turn a series of mostly harmless attacks into a single very dangerous one.

Patchstack customers are protected from this vulnerability. We still recommend updating to the most recent available version of WordPress immediately.

✌️ Our users are protected from this vulnerability. Are yours?

Web developers

Mitigate vulnerabilities in real-time without changing code.

See pricing
Plugin developers

Identify vulnerabilities in your plugins and get recommendations for fixes.

Request audit
Hosting companies

Protect your users, improve server health and earn additional revenue.

Patchstack for hosts

The trick: two interpretations of one value

WordPress lets site administrators preview or install themes straight from the WordPress.org catalog without leaving the WordPress admin panel. That flow passes a theme’s slug through the URL, and the value gets read twice, by two different pieces of code that handle the value differently.

On the server side, the WordPress.org Themes API sanitizes it. Extra characters get stripped, so something like twentytwenty"]> collapses to twentytwenty by the time the API responds. On the frontend, wp-admin‘s own JavaScript takes the same raw value, but drops it directly into a jQuery selector string without any sanitization.

This mismatch is the whole vulnerability. A specially crafted slug can be used to trick the page into thinking the person viewing the page clicked “Install” on a completely unrelated theme.

From forced install to full compromise

By itself, a silently-installed inactive theme isn’t a huge risk. Without being enabled in WordPress, most of the time an inactive plugin/theme is essentially inert. However, there is one time where an “inactive” theme is turned on, and that’s when previewing a theme in the WordPress Customizer.

pwn.ai’s full chain used a real catalog theme, Mobile Repair Zone 2.5.4, as the second stage. First the crafted-URL trick installs the theme, then a follow-up link is used to load the WordPress Customizer with Mobile Repair Zone active. This causes the theme’s functions.php to run and register its hooks, including an AJAX handler that accepted a plugin download URL with no nonce check and no capability checks at all. By passing a URL to an attacker-owned ZIP file to that AJAX action, WordPress will treat the malicious ZIP as a regular plugin, downloading it and executing it server-side, no questions asked. That’s what changes this from “an inactive theme appeared” to “the attacker has a working shell.”

What this actually takes to pull off

Reading “no attacker account needed” and “remote code execution” back to back makes this sound like a drive-by. It isn’t quite that, and clarifying how this attack can be triggered is important.

This attack starts with a specially crafted URL, so is similar to most CSRF attacks. It requires a site’s administrator to actually load that URL; a regular viewer (or even a more privileged account, like an Author or Editor) can’t trigger it. This can be triggered one of two ways: either an attacker gets a specific admin to click a specific link while logged in (a targeted phishing attack against a specific person, and one that requires that person interact with the malicious link), or through an XSS injection in the website which, when an Admin views it, can fire the request automatically in their browser. The second case means an attacker already had a foothold in the website; there would have had to be another component already vulnerable to XSS injection, and Click2Shell was just one of several ways an attacker could take advantage of that exploit.

The full RCE outcome specifically also depends on the target site installing a vulnerable theme. In cases where a site is unable to install new themes, such as when DISALLOW_FILE_MODS is enabled, an injection attack could still happen, but its impact doesn’t extend to new themes or plugins being installed on the website.

The fix

WordPress 7.1.1 closes this by scoping the vulnerable selector to real .theme DOM elements and running the slug through $.escapeSelector() before it gets injected into the selector string. The data is now treated as literal text instead of structural data, and can no longer click buttons by itself.

The broader point is less about this one selector and more about the shape of the bug: a URL parameter being processed on the backend and the frontend means it needs sanitized on both sides; it’s a pattern that can show up anywhere two different pieces of code parse the same input independently.

Like it? Share it.

Related articles