WPWithin covered WordPress 7.1.1’s security release yesterday, noting one of its 11 fixes closed “a way for crafted URLs to install and preview an inactive theme.” Security researchers at Patchstack have since published a deeper look at that fix, and it turns out to be more serious than a short description suggests: a chained attack researcher Paulos Yibelo of pwn.ai named Click2Shell, which could let an attacker run code on a vulnerable site.
What happened
WordPress lets administrators install and preview themes from the WordPress.org catalog without leaving the admin dashboard. That feature passes a theme’s identifying name, its slug, through the page’s URL, and two different parts of WordPress read that value differently.
The server-side code strips out unsafe characters before checking the slug against the WordPress.org theme catalog. But the admin dashboard’s own JavaScript used the same raw, unfiltered value to find and interact with a theme’s element on the page. That mismatch let an attacker craft a malicious link that, when an administrator clicked it, would make the page behave as though the admin had clicked “Install” on a theme of the attacker’s choosing. Installing a theme this way can trigger code that downloads and runs a theme’s files, which is how the chain leads to an attacker running code on the server.
Who is affected, and what it takes to be at risk
An attacker needs an administrator to load a specially crafted link, typically through a phishing email or another vulnerability that plants a malicious link somewhere the admin will click it. Sites with the DISALLOW_FILE_MODS setting turned on, which blocks theme and plugin installation through the dashboard entirely, are protected from the worst outcome even without updating.
WordPress.org fixed the flaw by making the admin dashboard’s code check for the real theme element on the page directly, using jQuery’s escapeSelector() function to treat the slug as plain text instead of code. That fix shipped in WordPress 7.1.1 on September 17.
What to do
- Update to WordPress 7.1.1 if you have not already. Go to your WordPress Dashboard, click Updates, then click Update Now.
- If your site has automatic background updates turned on, it is likely already updated.
- Avoid clicking unfamiliar links while logged into your WordPress admin dashboard, a good habit regardless of this specific bug.
End of article