ProBackend
active vulnerability exploitation
1 hour ago8 min read

Public Exploits Released for Critical wp2shell RCE Vulnerabilities in WordPress Core — Patch Now

Critical unauthenticated remote code execution vulnerabilities in WordPress Core (CVE-2026-63030 and CVE-2026-60137) have been weaponized in the wild, requiring immediate patching to 7.0.2 or 6.9.5.

Public Exploits Released for the Critical wp2shell Remote Code Execution Vulnerabilities

Here's the short version: if you're running WordPress 6.9.x or 7.0.x and haven't patched yet, your site is exposed to a fully weaponized, unauthenticated remote code execution chain that requires no plugins, no theme modifications, and absolutely no login credentials. Public proof-of-concept exploits have been released on GitHub, and threat intelligence firm watchTowr has already confirmed in-the-wild exploitation.

The wp2shell attack is named for what it does — it turns a WordPress install into a shell. Discovered by Adam Kues of Searchlight Cyber and disclosed on July 17, 2026, the vulnerability chains two independent flaws in WordPress Core to take an attacker from zero access all the way to code execution on a default installation. WordPress.org responded by enabling forced automatic security updates across its entire install base, but that doesn't help sites that disabled auto-updates or were compromised before the patch landed.

Searchlight Cyber estimates more than 500 million websites run WordPress, which makes this one of the most impactful core vulnerabilities in the platform's history. The fact that it's unauthenticated and requires no user interaction elevates it well above the typical plugin or theme vulnerability that dominates WordPress security advisories.

Public Exploits Released for the Critical wp2shell Remote Code Execution Vulnerabilities

The Two Flaws That Make Up wp2shell

wp2shell isn't a single bug. It's two independent vulnerabilities that, when chained together, produce an unauthenticated RCE against WordPress installations running versions 6.9.0 through 6.9.4 and 7.0.0 through 7.0.1.

CVE-2026-63030 — REST API batch-route confusion. Introduced in WordPress 6.9, this flaw lives in the /wp-json/batch/v1 endpoint, which is enabled by default on every WordPress install. The batch endpoint processes multiple REST API sub-requests in a single POST body, but a logic error causes request handlers to become misaligned when one sub-request fails validation. Specifically, a failed sub-request gets pushed into a validation array but skipped from the handler-matching array, which means request i gets dispatched with request i+1's handler and its own parameters. This desynchronization smuggles input past validation checks that would normally reject it.

CVE-2026-60137 — SQL injection in WP_Query. This is a high-severity SQL injection in the author__not_in parameter of WP_Query, affecting WordPress 6.8 and later. The bug is subtle: when author__not_in receives a string value instead of an array, it bypasses the is_array() guard and gets concatenated raw into a SQL WHERE clause. The sibling parameter author__in applies proper sanitization via array_map('absint', ...), but that guard is missing for author__not_in. A value like 0) AND (<condition>)-- - closes the NOT IN list and appends arbitrary SQL.

Alone, each flaw is serious but limited. CVE-2026-63030 requires the batch endpoint's confusion to smuggle a string past validation. CVE-2026-60137 alone can only be exploited through a facilitating plugin or theme that passes a raw string to WP_Query — core's REST API coerces the parameter to an integer array on 6.8.x. Together, they form a complete pre-authentication RCE chain that works against a stock WordPress install with nothing added.

The Two Flaws That Make Up wp2shell

How the Exploit Chain Works End to End

The full wp2shell attack chain is a multi-step process that an unauthenticated attacker can execute entirely over HTTP. Here's what it looks like in practice:

Step 1 — Route confusion. The attacker sends a POST to /wp-json/batch/v1 with multiple sub-requests. One sub-request has an invalid path that triggers a WP_Error, which creates the handler desynchronization. The next sub-request — targeting /wp/v2/posts with crafted parameters — gets dispatched with the handler from a different endpoint, bypassing its validation.

Step 2 — SQL injection via UNION. Through the confused handler, the attacker injects a UNION SELECT query into the author__not_in parameter. This forged post survives as a fabricated wp_posts row because the collection-only parameters (orderby=none, per_page=500) aren't validated against the single-post schema. The injection can extract data character-by-character using a boolean oracle — 0) AND (<condition>)-- - returns rows only when the condition is true.

Step 3 — Forge admin credentials. The attacker uses the SQL injection to read an existing administrator's user ID from wp_users, then creates forged oembed_cache and customize_changeset rows with that admin's ID. Triggering the oEmbed cache causes the customizer changeset to execute in the context of that administrator.

Step 4 — Create a rogue admin. With the borrowed admin context, the attacker posts to /wp/v2/users with roles:["administrator"], creating a new administrator account (typically prefixed with wp2_ or w2s_).

Step 5 — Upload a webshell. The attacker authenticates with the newly created credentials, uploads a malicious plugin via update.php?action=upload-plugin, and achieves remote code execution. In verified PoC demonstrations, this results in uid=33(www-data) — full system-level access.

The entire chain takes a dozen to dozens of HTTP requests. Crucially, the decisive steps ride inside batch POST bodies that rarely appear in web server access logs, making database artifacts the primary forensic evidence rather than log files.

Why wp2shell Is Different From Typical WordPress Vulnerabilities

WordPress gets a bad rap for security, but the reality is that a highly impactful, unauthenticated SQL injection or remote code execution vulnerability in WordPress core is actually fairly rare, according to watchTowr CEO Benjamin Harris.

Most WordPress security issues live in plugins or themes — third-party code that site owners install voluntarily. wp2shell is different because it's in WordPress itself, meaning it reaches a bare install with nothing added. The entry point — the REST batch endpoint — is enabled by default on every installation.

There's one narrowing condition worth noting: the code-execution path depends on the site not using a persistent external object cache like Redis or Memcached, which changes how the underlying query is built. This reduces the blast radius for some larger deployments that run object caching, but it does nothing for the millions of stock installs that never touch an external cache.

The SQL injection alone (CVE-2026-60137) affects a broader version range — WordPress 6.8.0 through 6.8.5 — but on those versions it cannot be chained to remote code execution because the REST API batch-route confusion bug (CVE-2026-63030) was only introduced in 6.9. So 6.8.x sites face a high-severity SQL injection that requires a facilitating plugin or theme, while 6.9.x and 7.0.x sites face the full unauthenticated RCE chain.

Patching Status and Temporary Mitigations

The complete wp2shell attack chain has been fixed in WordPress 6.9.5 and 7.0.2. The SQL injection alone is fixed in 6.8.6.

WordPress.org enabled forced automatic security updates for all supported installations running affected versions, which likely protected the vast majority of the 200+ million live WordPress sites. But forced updates don't reliably reach sites that disabled auto-updates, run on custom hosting configurations, or were already compromised before the update landed.

Searchlight Cyber has published a live vulnerability checker at wp2shell.com that allows administrators to test whether their WordPress installations are vulnerable without running any destructive tests.

For organizations unable to immediately update, the advisory recommends two temporary mitigations:

  1. Install a plugin that blocks anonymous access to the REST API entirely. This prevents unauthenticated attackers from reaching the batch endpoint at all.
  2. Block /wp-json/batch/v1 and ?rest_route=/batch/v1 at the WAF level. Cloudflare has already deployed Web Application Firewall protections for both vulnerabilities across all plans, including free accounts proxied behind its platform.

Both mitigations should be treated as temporary measures only. WAF rules reduce exposure while customers update, but they are not a substitute for patching — a determined attacker may find ways around custom rules, and the underlying code remains vulnerable.

Affected and fixed versions at a glance:

  • WordPress 6.8.0–6.8.5: SQL injection only (no RCE chain) → fixed in 6.8.6
  • WordPress 6.9.0–6.9.4: Full unauthenticated RCE chain → fixed in 6.9.5
  • WordPress 7.0.0–7.0.1: Full unauthenticated RCE chain → fixed in 7.0.2

Incident Response: What Defenders Should Do Right Now

Given the availability of public proof-of-concept exploits and the first reported signs of in-the-wild exploitation, every WordPress administrator should treat this as actively exploited and act today.

Verify your version. Don't assume auto-updates reached you. Log into your WordPress dashboard and confirm you're running 6.8.6+, 6.9.5+, or 7.0.2+ depending on your branch.

Check for signs of compromise before you patch. If your site was compromised before the update landed, patching alone doesn't remove the attacker. Run a compromise scan and review your admin users for accounts you didn't create — rogue administrators typically use logins prefixed with wp2_ or w2s_ and email domains like @wp2shell.invalid or @wp2shell.shellcode.lol.

Reset every user password. The SQL injection can read the wp_users table, which means an attacker may already hold your password hashes. Force a reset for all accounts — administrators first — and encourage users to change that password anywhere else they reused it. WordPress 6.9 uses a $wp$2y$ password hash (bcrypt over HMAC-SHA384), which is crackable with standard tools like Hashcat.

Preserve evidence if anything looks off. Image the database and web root read-only before remediation. On a typical Linux WordPress host, check these locations:

  • Database: wp_users and wp_usermeta tables for unexpected administrator rows; wp_options for tampered active_plugins, siteurl/home, and injected _transient_ or object-cache entries
  • Web root: Look for recently modified PHP files (find DOCROOT -name "*.php" -newermt "2026-07-16")
  • Web server logs: /var/log/apache2/ or /var/log/nginx/ for REST batch entrypoint hits
  • PHP logs: /var/log/php*-fpm.log and per-directory error_log files
  • System auth: /var/log/auth.log, shell history for www-data, and cron jobs for persistence

One important caveat: a clean exploit run can leave almost nothing in the logs. The absence of log lines is not evidence of safety. Let the database rows and file timestamps lead, and use logs to corroborate source IP, timing, and entrypoint.

Free tooling from Eye Security — including a browser extension for quick triage and a WordPress plugin compromise scanner — can help identify whether your site shows indicators of compromise from this specific attack chain.

More blogs