wp2shell WordPress Flaw Unlocks Unauthenticated Code Execution

The wp2shell vulnerability chain allows unauthenticated code execution on millions of WordPress sites, with patches now available.

By Central
Two separate flaws, a batch-route confusion and SQL injection, combine to enable remote code execution.
Highlights
  • The wp2shell vulnerability chain uses two flaws: CVE-2026-63030 (batch-route confusion) and CVE-2026-60137 (SQL injection).
  • The full RCE chain is exploitable only on WordPress versions 6.9 and later, with patches in 6.9.5 and 7.0.2.
  • Administrators should verify their WordPress version immediately and apply the update if running vulnerable releases.

A critical unauthenticated remote code execution vulnerability chain in WordPress core, tracked as wp2shell, now has CVE identifiers, a published proof-of-concept, and a patch that went out Friday with WordPress versions 6.9.5 and 7.0.2. Two separate flaws — CVE-2026-63030, a REST API batch-route confusion, and CVE-2026-60137, a SQL injection — combine to let an anonymous HTTP request execute arbitrary code on a default WordPress installation with no plugins required. Every site running WordPress 6.9.0 through 6.9.4 or 7.0.0 through 7.0.1 was exposed until the forced auto-update began rolling out.

The Two Flaws Behind wp2shell

CVE-2026-63030 is the batch-route confusion found by Adam Kues at Assetnote, Searchlight Cyber’s attack surface management arm. It abuses WordPress’s /wp-json/batch/v1codecodecode endpoint, which processes multiple sub-requests in a single call by tracking them in two parallel arrays. An error in one sub-request knocks those arrays out of alignment by one position, causing a subsequent request to execute under the wrong handler — bypassing the endpoint’s allow-list entirely.

CVE-2026-60137 is a SQL injection in WordPress core’s WP_Querycodecodecode object, specifically in the author__not_incodecodecode parameter. When the parameter receives a string instead of the expected array, the validation check that would normally sanitize the input is skipped entirely, allowing the raw value to reach the database query. This injection alone affects WordPress 6.8.0 through 6.8.5, fixed in 6.8.6, but it only becomes a full RCE chain when combined with the batch-route confusion present from version 6.9 onward.

Version Exposure and Patch Status

WordPress shipped forced updates on Friday, but the company has not confirmed whether those updates reach sites that have disabled automatic updates. Administrators should verify their current version manually rather than assume the patch landed.

  • 6.8.0 through 6.8.5: SQL injection only; fixed in 6.8.6
  • 6.9.0 through 6.9.4: Full RCE chain; fixed in 6.9.5
  • 7.0.0 through 7.0.1: Full RCE chain; fixed in 7.0.2

WordPress 7.1 beta2 carries both fixes. The RCE chain is only exploitable on versions 6.9 and later, which means every exposed site is running a release less than eight months old. While WordPress powers over 500 million websites, the exact number running vulnerable versions has not been disclosed.

CVSS Scores and Real-World Risk

The scoring picture is worth close attention. WordPress’s own advisory rates the RCE chain as Critical, but the CVE record assigns CVE-2026-63030 a CVSS score of 7.5 (High). That score reflects only the data-access impact of the batch-route confusion alone, not the integrity or availability loss that code execution implies. The SQL injection carries a score above 9.1 (Critical) because it directly reaches the database. Track both CVEs independently — the label on either one does not tell the full story.

One condition narrows the blast radius: the full code-execution path only works when the site is not running a persistent object cache such as Redis or Memcached. A default WordPress installation has no such cache, so default-install exposure remains. Sites using a persistent cache may be off this particular attack path, but that is a side effect of the architecture, not a fix, and it does not protect against the SQL injection component.

As of July 18, the vulnerability is not on CISA’s Known Exploited Vulnerabilities catalog, and no confirmed exploitation has been reported. With the proof-of-concept now public on GitHub and the patch available for anyone to read, that window is closing rapidly.

Mitigations for Sites That Cannot Patch Immediately

Every mitigation strategy focuses on keeping anonymous callers away from the batch endpoint. All are stopgaps and may break legitimate integrations:

  • At the WAF level, block both /wp-json/batch/v1codecodecode and rest_route=/batch/v1codecodecode. Blocking only the /wp-jsoncodecodecode path leaves the query-string route open. Cloudflare’s managed WAF now blocks the chain for sites behind it.
  • Use a plugin that disables unauthenticated REST API access entirely, such as a tool that kills anonymous REST requests wholesale.
  • Deploy a short drop-in plugin that rejects anonymous /batch/v1codecodecode requests at the rest_pre_dispatchcodecodecode hook. Searchlight has published one such plugin.

WordPress core is open source, and the patch names the files it changed. Shipping the fix necessarily ships the map to the bug. The only remaining lever is how quickly the update reaches sites before an attacker reads the same diff. WordPress pushed hard on Friday, but with the exploit now public and the update still rolling out, the race between patching and scanning is underway.

What Administrators Should Do Now

Verify your WordPress version immediately by checking the admin dashboard or running wp core versioncodecodecode from the command line. If your site is on 6.9.0 through 6.9.4 or 7.0.0 through 7.0.1, apply the update to 6.9.5 or 7.0.2 without delay. Even if you are on 6.8.x, apply 6.8.6 to close the SQL injection. If you cannot update immediately, block the batch endpoint at your WAF and monitor for unauthorized access. Enable multi-factor authentication on all admin accounts, audit active sessions, and consider a web application firewall with virtual patching capabilities. Mass exploitation of WordPress is a well-established threat, and this bug works on the default configuration with no preconditions. Treat the patch as urgent even though no active exploitation has been confirmed — the gap between public disclosure and automated scanning has historically been measured in hours, not days.

Share This Article