The WordPress security team shipped an emergency release on July 17, 2026 for a two-CVE chain researchers are calling wp2shell — a pre-authentication attack path that starts with SQL injection in WordPress core and ends with an attacker holding admin credentials and a webshell. No plugin required. No user interaction required. WordPress 7.0.2 forces automatic updates given the severity, and if your sites haven’t already pulled it, treat this as a today problem.

What happened

The chain is two separate bugs that only become dangerous together:

CVE-2026-60137 is a SQL injection in the author__not_in parameter of WP_Query, the internal class behind almost every database read WordPress performs. On its own, this parameter is only reachable by an authenticated user — WordPress core normally blocklists it from anonymous requests.

CVE-2026-63030 is a route-confusion flaw in WP_REST_Server::serve_batch_request_v1(), the handler for the REST API’s batch-request feature. By nesting a batch request inside itself, an attacker can desync the server’s internal bookkeeping so that a subrequest gets matched to a route/handler context it was never meant to reach. Researchers found that nesting the trick twice is enough to slip past the method allowlist that’s supposed to keep unauthenticated traffic away from WP_Query’s more dangerous parameters.

Chained, the effect is: an anonymous attacker hits the public REST API, uses the batch-route confusion to smuggle a malicious author__not_in value into WP_Query, and gets a blind SQL injection with zero authentication. From there, the documented path is not a direct RCE primitive — it’s a database dump. The attacker pulls the wp_users table, cracks or brute-forces the admin password hash offline, logs in as admin, and uploads a plugin or theme file containing a webshell through WordPress’s normal (and, for an admin, entirely legitimate-looking) file upload paths. Hence the name: wp2shell.

Affected versions and fix

  • WordPress 6.9.0–6.9.4 and 7.0.0–7.0.1 are affected by the full chain.
  • WordPress 6.8.x is affected by the SQL injection component only (CVE-2026-60137); a fix was backported to 6.8.6.
  • Fixed in 7.0.2 (and the 6.8.6 backport). WordPress enabled forced background updates for this release given the severity — most sites with auto-updates enabled should already be patched, but managed hosts, sites that disabled core auto-updates, or air-gapped/self-hosted installs need manual verification.

Impact

WordPress core powers a substantial fraction of the web, and this chain requires no third-party plugin, no theme, and no prior account — just a reachable REST API endpoint, which is the default configuration on essentially every WordPress install. Once an attacker has valid admin credentials, they have every capability an admin has: arbitrary PHP execution via plugin/theme editors or uploads, database access, and a foothold to pivot into whatever else shares the hosting environment (other tenants on shared hosting, adjacent services on the same VM, CI/deploy credentials stored in the WordPress config). Cloudflare and other WAF vendors pushed emergency rule updates to detect the nested-batch-request pattern, which is a signal of how quickly this is expected to be weaponized at scale — PoC exploit code is already circulating publicly.

Mitigation

  1. Patch to 7.0.2 (or the 6.8.6 backport) immediately. Don’t rely on background auto-updates alone — verify the version on every site, especially ones behind managed hosting panels or custom deploy pipelines that may have disabled core auto-updates.
  2. Rotate admin credentials and any secrets stored in wp-config.php on sites that were running an affected version with the REST API exposed, since a successful SQLi run prior to patching could have exfiltrated password hashes undetected.
  3. If you can’t patch immediately, disable or rate-limit the REST API batch endpoint (/wp-json/batch/v1) at the WAF/reverse-proxy layer — Cloudflare, Wordfence, and other WAF vendors have published signature updates for the nested-batch pattern.
  4. Audit for indicators of compromise: unexpected admin accounts, unfamiliar plugin/theme files with recent modification times, and anomalous REST API traffic in access logs predating the patch.
  5. Check whether auto-updates actually ran. WordPress’s forced-update mechanism has historically had gaps on sites with certain hosting configurations or update-blocking security plugins — don’t assume the emergency push reached every install.

References: The Hacker News writeup, VulnCheck’s technical analysis, Aikido Security’s exploit chain breakdown, and the WordPress 7.0.2 release notes.