ofensiva
wp2shell
CVE-2026-63030
CVE-2026-60137

wp2shell: Unauthenticated RCE in WordPress Core

Analysis of wp2shell (CVE-2026-63030 and CVE-2026-60137): the chain that achieves unauthenticated remote code execution in WordPress core. Impact, versions, detection and mitigation.

Secra Solutions teamJuly 20, 202614 min read

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 share 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

  • A chain of two WordPress core CVEs: CVE-2026-63030 (REST API batch route confusion) and CVE-2026-60137 (SQL injection in author__not_in of WP_Query).
  • Chained together they yield unauthenticated remote code execution (RCE) on a stock WordPress install, with zero plugins.
  • Versions affected by the full chain: 6.9.0 to 6.9.4 and 7.0.0 to 7.0.1. The SQL injection alone also reaches 6.8.x.
  • Fixed in 6.9.5, 7.0.2 and, for the injection component, 6.8.6.
  • Public PoCs exist and first signs of in-the-wild exploitation have been reported. Immediate patch priority.
  • Urgent mitigation if you cannot patch yet: block /wp-json/batch/v1 and ?rest_route=/batch/v1 at the WAF and restrict the REST API to authenticated users.

What wp2shell is

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.

The two vulnerabilities in the chain

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.

CVE-2026-63030: REST API batch route confusion

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.

CVE-2026-60137: SQL injection in author__not_in

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.

How they chain

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.

Severity and CVSS score

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.

Affected and fixed versions

BranchAffected versionsFixed inScope
6.8.x6.8.0 to 6.8.56.8.6SQL injection only (CVE-2026-60137), not the RCE chain
6.9.x6.9.0 to 6.9.46.9.5Full RCE chain
7.0.x7.0.0 to 7.0.17.0.2Full RCE chain

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.

Disclosure timeline

  • 17 July 2026: coordinated disclosure of the vulnerability. Researchers withhold technical details to allow time to patch.
  • 18 July 2026: WordPress publishes fixed versions 6.8.6, 6.9.5 and 7.0.2. Automatic update rollout begins.
  • Hours after disclosure: multiple public PoCs appear in GitHub repositories.
  • Around 20 July 2026: the full technical breakdown is published and several teams (among them watchTowr and Tenable) report the first signs of in-the-wild exploitation over the following weekend.

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.

Why it matters specifically

Three factors make wp2shell a first-order risk:

  1. No authentication and no plugins. No account, no vulnerable plugin and no particular configuration are needed. A reachable WordPress instance on an affected version is enough. That removes almost every usual barrier to exploitation.
  2. WordPress scale. WordPress is the most widely deployed CMS in the world. The attack surface is enormous and trivially enumerable with reconnaissance tools such as Shodan or Google dork queries, which identify exposed versions in minutes.
  3. RCE impact. Code execution on the web server opens the way to persistent webshells, data theft, pivoting into the internal network and backdoor deployment. A webshell installed this way behaves from then on like any backdoor: the difference is in the origin, not the outcome.

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.

How to detect exposure and compromise

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

Identify exposure:

  • Inventory every WordPress instance in the organisation, including marketing sites, old campaigns, subdomains and the ones no team claims as their own. Shadow IT is where the unpatched instances live.
  • Check the exact version of each install and compare it against the affected-versions table.
  • Verify whether automatic updates are enabled and whether the patch actually applied. Do not assume it did: confirm it.

Hunt for indicators of compromise (threat hunting):

  • Anomalous requests to /wp-json/batch/v1 or ?rest_route=/batch/v1 in the server and WAF logs, especially malformed or repetitive batches from unusual IPs.
  • Unusual SQL errors or strange queries in the database logs around the exposure dates.
  • New or unexpected administrator users, plugins or mu-plugins nobody installed, and suspicious files in wp-content/uploads (a classic webshell location).
  • Modifications to core files versus the official distribution, and anomalous outbound connections from the web server.

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.

Priority mitigations

Action one: patch now

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.

Action two: block the batch endpoint at the WAF

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.

Action three: restrict the REST API to authenticated users

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.

Action four: investigate and remediate if there was exposure

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.

Fit with NIS2, DORA and vulnerability management

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

  • NIS2, article 21: requires risk management measures that include vulnerability handling and disclosure. A patch window measured in hours is precisely the scenario these controls exist for.
  • NIS2, incident notification: if a compromised instance processes in-scope services, the notification deadlines apply (early warning within 24 hours, notification within 72 hours).
  • DORA, for financial entities: ICT third-party risk management and operational resilience explicitly cover disciplined patching of components such as a corporate CMS.
  • GDPR: if an exploit exfiltrates personal data, it may constitute a notifiable breach. Document the risk assessment.

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.

Frequently asked questions

Am I affected if my WordPress has no plugins?

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.

Do WordPress automatic updates protect me?

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.

If I update now, am I safe even if I was exposed before?

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.

Does blocking the /wp-json/batch/v1 endpoint at the WAF help?

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.

What is the difference between CVE-2026-63030 and CVE-2026-60137?

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.

How do I locate every WordPress instance in my organisation?

Combine the formal asset inventory with external reconnaissance (device search 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.

Assessing wp2shell exposure with Secra

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 contact.

About the author

Secra Solutions team

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.

Share article