wp2shell: a REST API batch routing flaw leads to SQL injection, then to an administrator account
Two WordPress core flaws chain into one unauthenticated path that needs no plugin: a request to /wp-json/batch/v1 can reach SQL injection in WP_Query and then create an administrator account. The fix is per branch, not one version.
What happens
CVE-2026-63030: the batch endpoint /wp-json/batch/v1 resolves the route incorrectly when several calls are folded into one request, so a call can run under another route's identity.
CVE-2026-60137: the author__not_in parameter of WP_Query is not sanitised properly, which leads to SQL injection when a plugin or theme passes untrusted input into it.
Chained, an unauthenticated attacker walks through the batch endpoint to the SQL injection, then creates an administrator account — on a default install, with no plugin at all. Releases before 6.8 are outside the affected range.
The path in
POST /wp-json/batch/v1, or?rest_route=/batch/v1where the REST API travels as a parameter. The endpoint exists on a default install, so no extra condition is needed.- A
207 Multi-Statusin the access log for that endpoint means the request was processed, so the vulnerable path was reached — this is more than a probe. - A prefix-based mu-plugin does not cover it unless
/batch/v1is in its list: the endpoint still answers and still processes the request.
Which code runs
- Core on disk: the fix replaces core files; it is not a configuration switch. A patch inside a theme cannot close this.
- Backups and staging copies: they serve no requests, so they are not an entry point, but they are readable code on the same machine.
- Containers: with the WordPress image, core lives in a mounted volume; pulling a new image does not update a volume that holds core.
Running is not installed
- New core files take effect when PHP reads them again. Opcache usually revalidates on modification time, but restarting FPM is the certain way.
- WordPress auto-update can be off or broken: a site can sit on the vulnerable release for weeks after the fix shipped. Measure the version; do not trust the updater.
Affected and fixed versions
| Product | CVE | Affected | Fixed in |
|---|---|---|---|
| WordPress | CVE-2026-63030 | 7.0.x | 7.0.2 |
6.9.x | 6.9.5 | ||
| WordPress | CVE-2026-60137 | 7.0.x | 7.0.2 |
6.9.x | 6.9.5 | ||
6.8.x | 6.8.6 |
Original description (WordPress · CVE-2026-63030): WordPress 6.9.x before 6.9.5 and 7.0.x before 7.0.2 is affected by a REST API batch endpoint route confusion issue which, combined with the author__not_in WP_Query SQL Injection (CVE-2026-60137), could allow an attacker to perform SQL Injection and achieve Remote Code Execution.
Original description (WordPress · CVE-2026-60137): WordPress 6.8.x before 6.8.6, 6.9.x before 6.9.5, and 7.0.x before 7.0.2 does not properly sanitise the author__not_in parameter of WP_Query, which could allow SQL Injection when a plugin or theme passes untrusted input to the parameter.
What to do
- Update within the line you already run; do not jump several majors on a site serving customers.
- After the update: verify core checksums, review administrator accounts, and look for PHP files modified after disclosure.
- If you cannot update yet: block
/wp-json/batch/v1and?rest_route=/batch/v1at the proxy or WAF, and log every request to that path.
Check yourself
wp core versionTells you: the core release in use
wp core verify-checksumsTells you: whether core files were modified
wp user list --role=administrator --fields=ID,user_login,user_registeredTells you: administrator accounts and when they registered — an unknown one after disclosure is a signal
grep -c 'batch/v1' /var/log/apache2/access.logTells you: requests to the batch endpoint; read the status codes beside them
wp plugin list --status=must-useTells you: which mu-plugin blocks which path
Sources
- CVE-2026-63030 — WordPress
- CVE-2026-60137 — WordPress
- WordPress.org releases
- NVD CVE-2026-63030
Written from the original advisory and the vendor's documentation; versions come from the site's data, updated 2026-11-10. Where they differ, the original advisory wins.