WordPress REST batch-route and WP_Query SQL boundary chain¶
Sources: WordPress 7.0.2 security release, CVE-2026-60137, CVE-2026-63030, and the CISA KEV catalog. CISA added both CVEs on 2026-07-21 and describes the pair as a chain that can reach unauthenticated remote code execution on affected default installations.
This page is not a generic patch alert. The durable operator lesson is to test framework chains one boundary at a time: a REST batch router may interpret a subrequest differently from the target route, while a query abstraction that is safe for typed callers can become injectable when an extension passes attacker-controlled values into it.
Lab or explicitly approved customer validation only
These CVEs are in KEV. Do not replay the active chain against an internet-facing site. Use a disposable WordPress lab with synthetic posts/users, no real plugins, credentials, media, database, mail, or outbound access. Stop at a boolean or timing-free synthetic query differential; do not attempt code execution, file writes, account creation, credential access, or persistence.
Confirmed scope¶
| CVE | Confirmed affected line | Boundary |
|---|---|---|
| CVE-2026-60137 / GHSA-fpp7-x2x2-2mjf | WordPress 6.8 before 6.8.6, 6.9 before 6.9.5, and 7.0 before 7.0.2 | A plugin or theme can pass untrusted author__not_in input into WP_Query; core did not sanitize that parameter correctly. This is facilitated SQL injection, not a universal unauthenticated core route by itself. |
| CVE-2026-63030 / GHSA-ff9f-jf42-662q | WordPress 6.9 before 6.9.5 and 7.0 before 7.0.2 | REST API batch-route confusion can expose the query boundary and chain with CVE-2026-60137. WordPress 6.8 is not listed as affected by this second issue. |
Versions before 6.8 are not affected according to the vendor release. WordPress also shipped fixes in 7.1 beta 2.
Recon and reachability¶
- Confirm WordPress ownership and exact core version from approved inventory, authenticated Site Health output, package manifests, or a lab image. Do not rely on generator tags alone.
- Inventory the REST API root and batch endpoint from WordPress route discovery. Record whether the batch route is present, whether authentication is required, and which methods/subroutes it accepts.
- Inventory plugins/themes or custom code that pass request-derived data to
WP_Query, especiallyauthor__not_in. For CVE-2026-60137 alone, document the exact extension-to-core call path; core version presence does not prove reachability. - Build a route matrix for direct target-route requests versus the same harmless request wrapped as a REST batch subrequest. Record route, method, authentication decision, argument schema, normalized parameter type, and handler reached.
Marker-only chain validation¶
Seed a disposable database with two synthetic authors and uniquely marked public posts. Preserve a normal direct request and normal batch request as controls. Then vary only the author__not_in representation across an integer, integer array, duplicate value, string form, malformed delimiter/quote canary, and the upstream regression fixture if it is available in the vendor test suite.
Capture these boundaries separately:
- Batch interpretation: Does the outer batch router authenticate, normalize, or validate the subrequest differently from a direct request to the same route?
- Type transition: What raw value reaches the route callback, extension, and
WP_Query? Record types rather than sensitive SQL text. - Query construction: Does the generated prepared-statement/parameter trace retain the value as data, or does query structure change?
- Observable proof: Does only the synthetic public result set change in a way the typed control cannot produce?
Use database query logging only in the disposable lab and redact unrelated statements. Avoid time-delay, stacked-query, file, user-table, option-table, or database-function payloads. A safe finding is unauthenticated batch subrequest -> parameter type/route confusion -> extension passes attacker-controlled author__not_in -> synthetic WP_Query result differs.
Negative controls and reporting¶
- Compare 6.8.6, 6.9.5, or 7.0.2 with the matching affected release.
- Repeat the target route directly, outside the batch wrapper.
- Remove or replace the extension call path that forwards untrusted
author__not_in. - Use a typed integer-array request that should produce the intended exclusion.
- Show that an unrelated malformed parameter is rejected, preventing a generic “REST accepts bad input” claim.
- State whether only CVE-2026-60137 is reachable or whether the CVE-2026-63030 batch-route precondition is also proven.
- Do not claim RCE from SQL behavior alone. The report must keep query injection, privilege/context, and any execution sink as separate boundaries; this workflow intentionally stops before the final sink.