wp2shell: WordPress core REST batch route confusion (CVE-2026-63030) and WP_Query SQLi (CVE-2026-60137) chain into unauthenticated RCE
Hacktron analyzes wp2shell, an unauthenticated RCE chain in WordPress core found by Searchlight Cyber. It combines CVE-2026-63030, a route handler confusion in the REST API batch endpoint, with CVE-2026-60137, an SQL injection in WP_Query. Affected versions are WordPress 6.9.0-6.9.4, 7.0.0-7.0.1 and the 7.1 beta, fixed in 6.9.5, 7.0.2 and 7.1 beta2. The article traces both flaws to historical fixes (Trac tickets #63502 and #59516, PR #8850) that introduced regressions. It then tests whether modern AI code review tools and SAST would have caught them: most general reviewers found the bug but missed the security impact on the routing flaw, and the rule-based SAST tools found neither. Hacktron says it reproduced the full RCE but is withholding the PoC until the chain is widely known and exploited.
Technical Details
- CVE-2026-63030: in
serve_batch_request_v1(), a sub-request with an unparsable URL (e.g.http://) pushes aWP_Erroronto$validation[]and hitscontinuewithout appending to$matches[]. The arrays desync by one, so a sub-request is validated against one route's schema but dispatched with another route's handler. Nesting a/batch/v1call inside a/wp/v2/postssub-request skips validation of the innerrequestsarray, which allows GET sub-requests that the batch schema normally rejects. The flaw bypasses schema validation, not the permission checks. The endpoint is reachable atPOST /wp-json/batch/v1or/?rest_route=/batch/v1. - CVE-2026-60137: a change to improve
WP_Querycache keys stopped applyingabsinttoauthor__not_inwhen it is a string, so only the array branch is sanitized. On its own it needs a plugin or theme that passes untrusted strings. Chained with the route confusion, theauthor_excludequery parameter reaches the posts handler unsanitized, giving SQLi (the example payload extractsuser_passfromwp_usersusing boolean-based blind injection). - In the review experiment, Cursor, Devin, Codex, Greptile and Claude flagged the batch change as a functional bug (500 error, wrong response, uncaught exception) but not as a security issue. Codex, Devin, CodeRabbit and Claude identified the SQLi, while Greptile did not. The three SAST tools tested caught neither issue, and CodeQL does not support PHP.
Remediation
- Update WordPress to 6.9.5, 7.0.2 or 7.1 beta2 or later.
- Treat security-critical PRs with security-focused review in addition to general code review, since general reviewers often miss the trust-boundary impact.
Exploit público
Há código de exploração publicado no Exploit-DB para CVE-2024-4577. O código não é reproduzido aqui: o link leva à fonte, e a explicação foi escrita pela IA a partir do arquivo publicado.
-
PHP CGI Module 8.3.4 - Remote Code Execution (RCE)
This script exploits CVE-2024-4577, an argument injection flaw in PHP running as CGI on Windows, where a soft hyphen in the query string is turned into a dash and lets the attacker pass configuration options to the interpreter. It needs only network access to an exposed php-cgi executable, with no login or user interaction. The options make PHP run code sent in the request body, giving command execution as the web server user. It looks like a working exploit with multi-host scanning and an interactive shell.
Linha do tempo
-
wp2shell: WordPress core REST batch route confusion (CVE-2026-63030) and WP_Query SQLi (CVE-2026-60137) chain into unauthenticated RCE
This Hacktron write-up adds root-cause detail on how each flaw was introduced (Trac tickets #63502 and #59516, PR #8850), the off-by-one `$validation`/`$matches` desync mechanics and nested-batch payload structure, and the affected 7.1 beta (fixed in beta2). It also reports that Hacktron reproduced the full RCE but is withholding the PoC, and evaluates AI code review and SAST tools against the original vulnerable PRs.
ler a análise desta fonte ocultar
This Hacktron write-up adds root-cause detail on how each flaw was introduced (Trac tickets #63502 and #59516, PR #8850), the off-by-one
$validation/$matchesdesync mechanics and nested-batch payload structure, and the affected 7.1 beta (fixed in beta2). It also reports that Hacktron reproduced the full RCE but is withholding the PoC, and evaluates AI code review and SAST tools against the original vulnerable PRs.Hacktron analyzes wp2shell, an unauthenticated RCE chain in WordPress core found by Searchlight Cyber. It combines CVE-2026-63030, a route handler confusion in the REST API batch endpoint, with CVE-2026-60137, an SQL injection in
WP_Query. Affected versions are WordPress 6.9.0-6.9.4, 7.0.0-7.0.1 and the 7.1 beta, fixed in 6.9.5, 7.0.2 and 7.1 beta2. The article traces both flaws to historical fixes (Trac tickets #63502 and #59516, PR #8850) that introduced regressions. It then tests whether modern AI code review tools and SAST would have caught them: most general reviewers found the bug but missed the security impact on the routing flaw, and the rule-based SAST tools found neither. Hacktron says it reproduced the full RCE but is withholding the PoC until the chain is widely known and exploited.Technical Details
- CVE-2026-63030: in
serve_batch_request_v1(), a sub-request with an unparsable URL (e.g.http://) pushes aWP_Erroronto$validation[]and hitscontinuewithout appending to$matches[]. The arrays desync by one, so a sub-request is validated against one route's schema but dispatched with another route's handler. Nesting a/batch/v1call inside a/wp/v2/postssub-request skips validation of the innerrequestsarray, which allows GET sub-requests that the batch schema normally rejects. The flaw bypasses schema validation, not the permission checks. The endpoint is reachable atPOST /wp-json/batch/v1or/?rest_route=/batch/v1. - CVE-2026-60137: a change to improve
WP_Querycache keys stopped applyingabsinttoauthor__not_inwhen it is a string, so only the array branch is sanitized. On its own it needs a plugin or theme that passes untrusted strings. Chained with the route confusion, theauthor_excludequery parameter reaches the posts handler unsanitized, giving SQLi (the example payload extractsuser_passfromwp_usersusing boolean-based blind injection). - In the review experiment, Cursor, Devin, Codex, Greptile and Claude flagged the batch change as a functional bug (500 error, wrong response, uncaught exception) but not as a security issue. Codex, Devin, CodeRabbit and Claude identified the SQLi, while Greptile did not. The three SAST tools tested caught neither issue, and CodeQL does not support PHP.
Remediation
- Update WordPress to 6.9.5, 7.0.2 or 7.1 beta2 or later.
- Treat security-critical PRs with security-focused review in addition to general code review, since general reviewers often miss the trust-boundary impact.
- CVE-2026-63030: in
-
wp2shell: CVE-2026-63030 and CVE-2026-60137 WordPress chain exploited in the wild for unauthenticated RCE
ler a análise desta fonte ocultar
F5 Labs reports that wp2shell, a WordPress attack chain combining CVE-2026-63030 (REST API batch route confusion) and CVE-2026-60137 (SQL injection via
author_exclude/author__not_inin WP_Query), enables unauthenticated remote code execution. Both flaws were published on July 17, 2026, have public proof-of-concept code, and were added to the CISA KEV Catalog. F5 Labs sensors captured a full exploitation attempt from 185.242.3.238, replayed identically against at least two US-based sensors, which indicates automated exploitation. The July report also notes continued attacker interest in older flaws affecting PHP, Microsoft Exchange, MobileIron and WordPress plugins. F5 notes that honeynet maintenance left gaps in telemetry, so month-over-month volume trends are less reliable.Technical Details
- CVE-2026-63030 (CWE-436): wrapping an inner batch structure inside an outer request to
/wp-json/batch/v1confuses the route dispatcher and reaches handlers that normally require authentication. It affects WordPress 6.9.x before 6.9.5 and 7.0.x before 7.0.2. - CVE-2026-60137 (CWE-89): improper sanitization of
author__not_in, exposed over HTTP as theauthor_excludeparameter, allows SQL injection. It affects 6.8.x before 6.8.6, 6.9.x before 6.9.5 and 7.0.x before 7.0.2. - The captured 735-byte payload is a UNION-based SQL injection delivered through nested batch requests. It uses a
||4f4b||marker (hex for "OK") to confirm success, hex-encodedpublishandpostvalues so the injected row looks like a legitimate post, andorderby=none&per_page=500. - The batch endpoint was also targeted via
/index.php?rest_route=/batch/v1and/?rest_route=/batch/v1, which work when pretty permalinks are disabled. - Other top batch-endpoint requesters: 47.129.160.40 (153 requests, AWS Singapore), 94.159.96.62 (64), 207.180.249.59 (38, Contabo) and 13.140.128.125 (24). Except for 185.242.3.238, these counts do not prove the traffic carried wp2shell payloads.
- F5 did not observe a web shell being deployed in the captured activity.
- Other CVEs active in July: CVE-2018-14028, CVE-2022-41040, CVE-2021-34473, CVE-2020-15505 and CVE-2024-4577.
Remediation
- Patch immediately to WordPress 6.8.6, 6.9.5, 7.0.2 or later.
- Monitor POST requests to the batch endpoint paths that contain nested
requestsarrays. - Alert on
author_excludevalues containing SQL metacharacters, UNION, SELECT, hex values or encoded equivalents. Do not rely onauthor__not_infor network detection. - Restrict unauthenticated REST API access where feasible.
- Hunt for unexpected PHP files, recently modified files, anomalous administrator accounts and unexpected outbound connections from the web tier.
- Treat source IPs as time-limited indicators and validate ownership before blocking.
- CVE-2026-63030 (CWE-436): wrapping an inner batch structure inside an outer request to