Skip to content
wp2shell: WordPress RCE (CVE-2026-63030)

wp2shell: WordPress RCE (CVE-2026-63030)

Secra.Es • July 20, 2026

wp2shell is a chain of two WordPress core vulnerabilities (CVE-2026-63030 and CVE-2026-60137) that, chained together, let an anonymous attacker achieve remote code execution (RCE) on a stock installation, with no authentication, no plugins and no special preconditions . It affects the 6.9.x and 7.0.x branches, was patched on 18 July 2026, and within hours public proof-of-concept exploits appeared. WordPress powers a huge of the web (500 million-plus sites in total are cited), so the potential for mass exploitation is high: any reachable, unpatched instance on an affected version is a target.

This Secra advisory summarises what wp2shell is, how the chain works at a high level, the affected and fixed versions, the disclosure timeline, how to detect exposure and compromise, and the priority mitigations. It contains no working exploit code: the intent is defensive.

Key takeaways on wp2shell

wp2shell (from "WordPress to shell") is the name under which an exploitation chain discovered in WordPress core itself, not in a third-party plugin or theme, was disclosed. That nuance is what makes it exceptional: serious WordPress vulnerabilities usually cluster in the plugin ecosystem, while the core receives intense scrutiny. A pre-authentication RCE chain in the core, applicable to clean installs, is a rare event and of maximum interest to defenders and attackers alike.

The chain was reported by Adam Kues of the Assetnote research team (part of Searchlight Cyber) for the route confusion component, while the SQL injection was reported by researchers TF1T, dtro and haongo. At initial disclosure the researchers deliberately withheld the deep technical details to give defenders time to patch. The full technical breakdown and the first proof-of-concept exploits became public after the patches were available.

wp2shell is not a single flaw, but the combination of two independent weaknesses that in isolation have limited impact and together escalate to code execution.

The /wp-json/batch/v1 endpoint (also reachable as ?rest_route=/batch/v1 ) lets you group several REST API sub-requests into a single HTTP call. One point that has been misreported is worth clarifying: the batch endpoint has existed in WordPress since version 5.6 (2020). What is new in the 6.9 branch is not the endpoint, but an error in how it processes the batch.

In essence, an error in one of the sub-requests knocks the internal arrays that WordPress uses to pair each request with its handler out of step by one. The result is that a sub-request ends up running under a different request's handler. That confusion allows the endpoint's allow-list to be bypassed and, without authentication, reaches handlers and parameters that under normal conditions would be out of reach for an anonymous user. It is the access vector that opens the door.

The second piece lives in the author__not_in parameter of the WP_Query class, present since WordPress 6.8. The code expects an array of identifiers. If it is handed a string instead, the type check that assumes an array is skipped and the unsanitised value ends up inserted directly into the SQL query. It is a textbook SQL injection caused by incomplete type validation.

In isolation, each flaw has a ceiling. The route confusion, on its own, gives access to data it should not expose, but not code execution. The SQL injection, on its own, requires reaching an entry point that normally demands an authenticated context. The point of wp2shell is that the first vulnerability hands an anonymous attacker access to the vulnerable sink of the second. Once the SQL injection is exploitable without authentication, it is leveraged to escalate to code execution on the server.

The technical breakdown published after the patches details that escalation, which is more elegant than a classic injection. The route confusion, which WordPress processes in the WP_REST_Server::serve_batch_request_v1() handler, allows the vulnerable query to be reached without authentication. From there, the SQL injection is not used only to read data: it poisons cached WP_Post objects through object hydration. The oEmbed write path persists those forged objects to the database and, through nested saves, a Customizer changeset and the REST API loader, WordPress ends up re-evaluating as an administrator a user-creation request it had previously rejected. The result is a forged administrator account that installs a plugin and, with it, executes code on the server. According to Cloudflare's analysis, this code-execution path works when the site does not use a persistent object cache, which a stock WordPress installation does not have, so default exposure stands.

Hence the name: from a request to a reachable WordPress, to a shell. It is the same pattern we study in any web application audit , where real impact almost never comes from an isolated flaw, but from chaining several together.

Precision matters here, because the sources do not agree and the reason is instructive. WordPress classified the full chain as critical. In its own advisory, however, it assigned CVE-2026-63030 a CVSS of 7.5 (High), reasoning that the route confusion alone permits data access, not the full integrity and availability loss we associate with code execution. Downstream aggregators and vendors (NVD and various security providers) scored the end-to-end unauthenticated RCE chain as critical, with values as high as 9.8.

The discrepancy is not an error, it is a lesson in how to read CVSS: scoring an isolated component is not the same as scoring the full exploitable chain. For patch prioritisation, what matters is not the exact number, but the verified fact that a route to unauthenticated RCE exists with a public PoC. That is top priority regardless of whether it is tagged 7.5 or 9.8. It is the same distinction between reported severity and real exploitability that we explain in what is an exploit .

Versions before 6.8 are not vulnerable to the SQL injection, and versions before 6.9 are not vulnerable to the RCE chain, because the route confusion error that provides the unauthenticated access is only present from the 6.9 branch onwards.

The pattern is the usual and dangerous one: public PoCs appeared within hours of disclosure and the first signs of real-world exploitation emerged around 20 July, so the window to patch before exploits are in circulation is measured in hours, not weeks. WordPress automatic updates protect many sites, but leave out those that have them disabled, those pinned to old versions by plugin incompatibility, and forgotten instances.

Three factors make wp2shell a first-order risk:

This is exactly the kind of exposure that an attack surface management (ASM and EASM) programme is designed to discover before the attacker does: inventory every published WordPress instance, know its version and prioritise patching the ones in range.

Detection has two planes: knowing whether you are vulnerable and knowing whether you have already been compromised.

Hunt for indicators of compromise (threat hunting):

One critical point: patching does not evict an attacker who already got in . If an instance was exposed during the exploitation window, you must assume potential compromise and investigate accordingly, not simply update.

The only real fix is to update to 6.8.6, 6.9.5 or 7.0.2 depending on the branch. It is the priority measure and admits no delay. After updating, confirm the installed version is the fixed one and do not take it for granted that automation did it for you.

If you cannot patch immediately, block both /wp-json/batch/v1 and ?rest_route=/batch/v1 at the WAF or edge. It is a temporary mitigation, not a substitute for the patch, but it cuts the access vector while you roll out the update. A well-configured WAF allows this virtual patching in minutes.

Limit anonymous access to the REST API, whether with a plugin that requires authentication for the API or with a custom mu-plugin that specifically restricts the batch endpoint to authenticated requests. Hardening REST API exposure is, moreover, a good permanent practice worth reviewing in any API audit .

If the instance was reachable while unpatched, activate the response procedure: retrospective threat hunting, core integrity review, rotation of stored credentials and database keys, and containment of any artefact found. A simple update does not remove an already-installed webshell.

wp2shell is a textbook case for illustrating why vulnerability management with patch SLAs and notification procedures is not bureaucracy, but operational control:

The difference between an organisation that absorbs wp2shell as a routine patch and one that ends up with a notifiable breach is not luck, but having the surface inventoried, exposure monitored and patching disciplined. It is the same logic we apply when analysing other recent maximum-severity advisories, such as CVE-2026-21858 in n8n or CVE-2026-34926 in Trend Micro Apex One , and that we summarise each month in our critical vulnerability roundup .

Yes. wp2shell affects WordPress core, not plugins or themes. A clean, stock installation on an affected version of the 6.9.x or 7.0.x branches is exploitable. The absence of plugins does not protect against this chain.

They help a great deal, but you should not take them for granted. Many sites have automatic updates disabled, are pinned to old versions by plugin incompatibility, or are forgotten instances. Manually confirm the installed version is 6.8.6, 6.9.5 or 7.0.2.

Updating closes the vulnerability, but does not remove an attacker who already got in, nor the webshells or accounts they created. If the instance was reachable while unpatched during the exploitation window, assume potential compromise and investigate before considering it safe.

Yes, as a temporary mitigation. Blocking /wp-json/batch/v1 and ?rest_route=/batch/v1 cuts the route confusion access vector while you roll out the patch. It is not a substitute for updating, but a bridge until you do.

CVE-2026-63030 is the route confusion in the REST API batch endpoint, which gives an anonymous attacker access to restricted handlers. CVE-2026-60137 is the SQL injection in author__not_in of WP_Query . The first provides the unauthenticated access; the second, chained, allows escalation to code execution.

Combine the formal asset inventory with external reconnaissance (device engines like Shodan, Google dork queries, subdomain discovery) and queries to marketing and product teams to identify unofficial instances. An attack surface management programme automates this discovery continuously.

Secra runs an internal vulnerability research programme with its own advisories published on NVD and INCIBE-CERT ( CVE-2025-40652 in CoverManager and CVE-2023-3512 in Setelsa ConacWin CB, among others). That discovery discipline applied to your exposed surface is the difference between detecting wp2shell exposure before or after the incident.

We help organisations assess their real exposure: inventory and continuous discovery of published WordPress instances, version and patch verification, REST API hardening review, retrospective threat hunting and, when applicable, incident response (DFIR) intervention. Express audit of exposed WordPress instances with first findings in under 5 days. Get in touch through .

Ethical hackers with OSCP, OSEP, OSWE, CRTO, CRTL and CARTE certifications, 7+ years of experience in offensive cybersecurity, and authors of CVE-2025-40652 and CVE-2023-3512.