A newly disclosed WordPress exploit chain, nicknamed “WP2Shell,” lets unauthenticated attackers achieve remote code execution (RCE) on any WordPress Core installation, no plugins required. Disclosed on July 17, 2026, the chain combines two vulnerabilities: CVE-2026-60137 (SQL injection) and CVE-2026-63030 (REST API batch-route confusion). WordPress shipped fixes in versions 6.8.6, 6.9.5, and 7.0.2, and took the unusual step of force-pushing the update to all supported installations through its auto-update system.
Because the vulnerability lives in WordPress core, every site running an affected version is exposed regardless of what is installed on top of it. Public proof-of-concept exploits are already circulating. Early signs of in-the-wild exploitation were reported within 24 hours of disclosure, making this a same-day patch priority for any internet-facing WordPress deployment.
What Is WP2Shell? Breaking Down CVE-2026-60137 and CVE-2026-63030
Risk Analysis — Combined Chain
| Chain Severity: | CRITICAL (unauthenticated remote code execution) |
| CVE-2026-60137 — SQL Injection: | CVSS v3.1 9.1 CRITICAL AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N |
| CVE-2026-63030 — Route Confusion: | CVSS v3.1 7.5 HIGH AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| Exploit available in public: | Yes. |
| Exploit complexity: | Low. |
| Affected Product: | WordPress Core WP_Query (author__not_in parameter) and the REST API batch endpoint (WP_REST_Server::serve_batch_request_v1) |
| Affected Installations: | WordPress 6.8.x–7.0.x branches, within an estimated 500 million+ global WordPress install base |
CVE-2026-60137 is a SQL injection vulnerability in WP_Query caused by improper sanitization of the author__not_in parameter. On its own, exploitation is gated behind an authentication blocklist. CVE-2026-63030 is a route-confusion vulnerability in the REST API batch endpoint that lets an anonymous request slip past that same blocklist. Chained together, the two vulnerabilities allow a completely unauthenticated leading anonymous attacker to inject SQL and ultimately execute arbitrary code on the server.
Successful exploitation of the full chain enables:
- Extraction of the WordPress database, including user password hashes, secret keys, and configuration data, plus creation of rogue administrator accounts
- Upload of malicious plugins or webshells, leading to arbitrary code execution on the underlying server
- Site defacement, service disruption, or full server compromise if the host is repurposed for further attacks
Root Cause: SQL Injection in WP_Query (CVE-2026-60137)
The author__not_in parameter of WP_Query is expected to receive an array. WordPress’s validation logic checks for that array type before sanitizing the value. If a string is passed instead of an array, that check is skipped entirely, and the raw, attacker-controlled string is dropped directly into the underlying SQL query. Any plugin, theme, or core code path that hands untrusted input to author__not_in becomes an injection point.
Root Cause: REST API Batch-Route Confusion (CVE-2026-63030)
Introduced when the REST API batch framework was extended in WordPress 6.9, the vulnerability sits inside WP_REST_Server::serve_batch_request_v1(). When a sub-request in a batch fails validation, the resulting WP_Error is pushed into an internal $validation[] array but is not added to the parallel $matches[] array used for routing. This creates a one-position index shift: sub-request “i” in the batch ends up being dispatched using the route handler intended for sub-request “i+1”. An attacker can use this mismatch to smuggle a request into a handler it was never meant to reach including one that bypasses the authentication check gating the WP_Query SQL injection.
The combination is what makes the chain dangerous: CVE-2026-63030 turns an authenticated-only SQL injection into one reachable by any anonymous visitor, and CVE-2026-60137 turns that access into a path to full database compromise and, from there, remote code execution.
Exploitation Flow: From Anonymous Request to Remote Code Execution
Public write-ups and proof-of-concept code describe the following general attack path. Exact technical detail remains partially withheld by the original researchers to slow mass exploitation.
- An anonymous attacker sends a crafted request to the REST API batch endpoint (/wp-json/batch/v1 or ?rest_route=/batch/v1) on a target running an affected WordPress version.
- The request is structured to trigger the route-confusion bug (CVE-2026-63030), causing WordPress to dispatch one sub-request using the handler meant for the next.
- This misrouting bypasses the authentication blocklist that would otherwise restrict access to the vulnerable WP_Query code path.
- The attacker supplies a malicious string to the author__not_in parameter, triggering the SQL injection (CVE-2026-60137) and extracting data such as administrator password hashes.
- Using the extracted credentials (or a further chained technique), the attacker gains administrative access, uploads a malicious plugin or webshell, and achieves arbitrary code execution on the server.
Some published proof-of-concept exploits claim a more direct pre-authentication path to code execution without requiring a cracked administrator password, which would shorten this chain further. Indusface recommends treating the vulnerability as pre-auth RCE regardless of which exploitation path is used.
Affected WordPress Versions and Patch Status
| CVE-2026-60137 (SQLi only): | WordPress 6.8.0–6.8.5, 6.9.0–6.9.4, 7.0.0–7.0.1 |
| CVE-2026-63030 (chainable to RCE): | WordPress 6.9.0–6.9.4, 7.0.0–7.0.1 |
| Not affected: | Versions prior to WordPress 6.8 |
| Fixed in: | WordPress 6.8.6, 6.9.5, 7.0.2, and 7.1 Beta 2 |
Sites on the 6.8.x branch are exposed to the standalone SQL injection. They are not exposed to the full RCE chain, since the REST API route-confusion bug was only introduced in 6.9.
Sites on 6.9.x and 7.0.x are exposed to the complete unauthenticated RCE chain. These should be treated as the highest priority for patching.
Mitigation and Remediation Steps for WordPress Site Owners
The only complete fix is upgrading WordPress core to a patched version. WordPress has enabled forced automatic updates for supported branches, but site owners should not assume this has reached every installation, auto-updates can be disabled, and hosting environments vary.
- Update immediately to WordPress 6.8.6, 6.9.5, or 7.0.2 (7.1 Beta 2 for beta-track sites). Verify the installed version directly rather than assuming the forced update has applied.
- Block anonymous access to the batch endpoint at the WAF or edge if an immediate update is not possible, both /wp-json/batch/v1 and the query-string form ?rest_route=/batch/v1 must be blocked, as filtering only one path leaves the other open.
- Disable the REST API for unauthenticated users as a temporary stopgap where the batch endpoint cannot be selectively blocked.
- Audit web server and application logs for anomalous requests to /wp-json/batch/v1, unexpected administrator logins, and unfamiliar plugin installations that may indicate exploitation.
- Rotate administrator credentials and review installed plugins for unauthorized changes if compromise is suspected, since exploitation of the SQL injection can expose password hashes.
- Prioritize sites running WordPress 6.9.x and 7.0.x, which are exposed to the full unauthenticated RCE chain, over sites on the 6.8.x branch.
AppTrana WAAP Coverage for CVE-2026-60137 and CVE-2026-63030
AppTrana customers are protected against exploitation attempts targeting this chain, including the WP_Query SQL injection and the REST API batch-route confusion.
Edge-level virtual patching blocks malicious payloads to author__not_in and anomalous batch-endpoint requests before they reach the application, regardless of which WordPress version is running underneath. This converts what would otherwise be a same-day patch emergency into a managed remediation window, giving teams time to test and roll out the WordPress core update without carrying open exposure in the interim.