WordPress 7.1.1 fixes Click2Shell chain to remote code execution

WordPress 7.1.1 fixes Click2Shell chain to remote code execution

WordPress 7.1.1 patches Click2Shell, a flaw that chained one admin click into a remote shell on sites running a vulnerable theme.

WordPress 7.1.1 has fixed a vulnerability that could let a single click by a logged-in administrator turn into a working remote shell on the server, according to an analysis published by Patchstack. The flaw, named Click2Shell, was reported responsibly by Paulos Yibelo of pwn.ai and closed in the 17 September WordPress release, with Patchstack's write-up by security researcher Chazz Wolcott published on 18 September. Patchstack states that its own customers are protected from the vulnerability, and recommends that everyone else update to the most recent available version of WordPress immediately.

The bug is less one mistake than a chain. Patchstack describes it as a Cross-Site Request Forgery (CSRF, a trick that makes a victim's logged-in browser send a request the victim never intended) combined with a selector injection (extra characters inserted into the code that looks up elements on a page, so it finds something different than intended). Neither weakness is dramatic on its own. Chained together, they turn a single click into code running on the site's server.

The mechanism sits in the way WordPress handles themes. Administrators can preview or install a theme directly from the WordPress.org catalog inside the admin panel, and that flow carries the theme's slug, its short identifying name, in the URL. According to Patchstack, that same value is then read twice by two different pieces of code, and the two do not agree on how to treat it. On the server side, the WordPress.org Themes API sanitizes the value and strips extra characters, so a crafted string such as twentytwenty"]> collapses back to twentytwenty by the time the API answers. On the front end, wp-admin's own JavaScript takes the identical raw value and drops it straight into a jQuery selector string, with no sanitization at all. jQuery is a widely used JavaScript library that helps web pages find and modify elements. That mismatch is the whole vulnerability: a specially crafted slug can convince the page that the person viewing it clicked Install on a completely unrelated theme.

On its own, a silently installed but inactive theme is not a big risk. As Patchstack notes, without being enabled in WordPress an inactive theme or plugin is essentially inert. There is one moment when an inactive theme does run, and that is when it is previewed in the WordPress Customizer. The full chain built by pwn.ai used a real catalog theme, Mobile Repair Zone 2.5.4, as its second stage. First the crafted URL installs the theme, then a follow-up link loads the Customizer with Mobile Repair Zone active. That causes the theme's functions.php file to execute and register its hooks, including an AJAX handler that accepted a plugin download URL with no nonce check (a nonce being a one-time code that proves a request came from your own session) and no permission checks of any kind. Handing that action a URL pointing to an attacker-owned ZIP file means WordPress treats the malicious archive as an ordinary plugin, downloads it and executes it on the server. That is the step that changes the outcome from an inactive theme appearing to an attacker holding a working shell.

Patchstack is explicit that this is not a drive-by attack, and the distinction matters. Reading no attacker account needed and remote code execution back to back can make it sound as though any visitor could trigger it, but the attacker has to get a site administrator to load a crafted URL. A regular viewer cannot trigger it, and neither can a more privileged account such as an Author or Editor. There are two routes. The first is a targeted phishing attack against a specific administrator who is logged in and interacts with the malicious link. The second is an XSS injection (Cross-Site Scripting, a flaw that lets an attacker place their own code into a page, where it runs in the browser of whoever views it) already present on the site, which fires the request automatically when an administrator looks at the page. That second route assumes the attacker already had a foothold, meaning some other component had to be vulnerable to XSS in the first place, and Click2Shell would be only one of several ways to exploit it. The full remote code execution result also depends on the target site being able to install a vulnerable theme. Where new themes cannot be installed, for example when DISALLOW_FILE_MODS is enabled, the injection could still occur, but its impact does not extend to installing new themes or plugins on the site.

WordPress 7.1.1 closes the issue in two moves. It scopes the vulnerable selector to real .theme elements in the document, and it runs the slug through $.escapeSelector() before the value goes into the selector string. The data is now handled as literal text rather than as structural data, so it can no longer click buttons by itself. Patchstack's wider point is that the lesson is less about this one selector than about the shape of the bug: when a URL parameter is processed on the back end and the front end, it needs sanitizing on both sides, and that pattern can appear anywhere two different pieces of code parse the same input independently.

For site owners, the practical takeaway is the same as for most WordPress fixes. Core updates are where this patch lands, and a update that is deferred is a window that stays open. Where the day to day of patching is the hard part, AEU Hosting, our managed WordPress hosting service, keeps the WordPress platform layer maintained for the sites it runs, and the details are set out at albhosting.eu. The theme selection habit matters too: an unused theme that stays installed is one more thing that can be made to run.

Click2Shell also illustrates why severity labels can mislead. Two weaknesses that would each be shrugged off, a request the browser should not have sent and a string that should have been escaped, become a server-side shell when they are combined, and no attacker account is required for either half. The honest reading of the Patchstack account is that the exploit was real, the fix is published, and the precondition is human: an administrator has to click, or something else on the site has to be serving injected code already.

How to Protect Yourself

  1. Log in to your WordPress dashboard, open the Updates screen and make sure you are running the newest version of WordPress, 7.1.1 or later.
  2. Never click a link about your website that arrives by email or message, even if it looks like it comes from a colleague or your hosting company; open your site by typing its address yourself instead.
  3. Ask whoever maintains your site, or your hosting provider, to switch on automatic updates for WordPress so security fixes arrive without anyone having to remember.
  4. Delete any theme or plugin you are not actively using, because an installed but unused theme can still be switched on without you noticing.
  5. Only install themes and plugins from the official WordPress catalog, not from links sent to you or from unknown download sites.
  6. If someone tells you your site sent them a strange or unexpected link, contact your hosting provider straight away so they can check it.

Terms Explained

  • CSRF (Cross-Site Request Forgery) A trick that makes your already logged-in browser send a request to a site you trust, without you meaning to do it.
  • remote code execution When an attacker manages to get their own program running on your server, which effectively hands them control of it.
  • sanitize To clean up information coming into a website by removing or neutralising characters that a computer might otherwise read as instructions.
  • selector injection Sliding extra characters into the part of a page's code that looks up which element to act on, so it acts on a different one instead.
  • jQuery A widely used piece of JavaScript that helps a web page find and change parts of itself.
  • nonce A one-time security code attached to a request to prove it really came from your own session on the site.
  • XSS (Cross-Site Scripting) A flaw that lets an attacker plant their own code into a page, so it runs in the browser of anyone who views that page.
  • slug The short name that identifies a theme or plugin in a web address.

Related AEU services