
WordPress Core Unauthenticated RCE (CVE-2026-63030, CVE-2026-60137)
__ ______ ____ ____ _ _ _____ _ _ \ \ / / _ \___ \/ ___|| | | | ____| | | | \ \ /\ / /| |_) |__) \___ \| |_| | _| | | | | \ V V / | __// __/ ___) | _ | |___| |___| |___ \_/\_/ |_| |_____|____/|_| |_|_____|_____|_____|wp2shell-checker | WordPress Batch API Desync Detector
Checker detector for the WordPress Core REST Batch API pre-auth RCE
Created by 0xjessie21 — Cybersecurity ILCS
| Signature | wp2shell / WP Core REST Batch API Desync |
| Severity | 9.8 CRITICAL — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| Affected versions | WordPress 6.9.0-6.9.4 and 7.0.0-7.0.1 |
| Fixed in | 6.9.5, 7.0.2 |
| Preconditions | None — unauthenticated, no plugins, default config |
| Mode | Non-destructive / read-only probe |
Screenshot of the tool detecting a vulnerable WordPress instance in an authorized internal VAPT engagement.

This tool is strictly for authorized security testing and defensive verification purposes only.
By using this tool you agree that you are solely responsible for ensuring your use complies with applicable law and your organization's authorization policies.
WordPress Core's REST Batch API (/wp-json/batch/v1) keeps three parallel arrays in sync while resolving a batch of sub-requests. An intentionally malformed sub-request desynchronizes them — causing every subsequent sub-request to be dispatched using the wrong handler and permission callback.
This tool sends one crafted batch request and inspects the response codes only, never crossing into a state-changing operation.
Verdict logic
| Result | Verdict |
|---|---|
block_cannot_read | VULNERABLE — permission check leaked from block-renderer handler |
rest_term_invalid | PATCHED — categories handler responded correctly |
Additionally, the tool performs passive WAF/CDN fingerprinting from response headers:
Cloudflare · Sucuri · Akamai · AWS CloudFront · Imperva · Fastly · F5 BIG-IP · Wordfence
# Basic scan
./wp2shell_checker.py https://your-site.com
# Multiple targets in one run
./wp2shell_checker.py https://site1.com https://site2.com https://site3.com
# Custom timeout
./wp2shell_checker.py https://your-site.com --timeout 20
# Show full raw request/response (payload, headers, body)
./wp2shell_checker.py https://your-site.com --raw
# Disable colors/animation (for logging to a file)
./wp2shell_checker.py https://your-site.com --no-color > scan_report.txt
All flags
If a target comes back VULNERABLE:
7.0.2 (or 6.9.5 on the 6.9 branch). Confirm the update actually applied./wp-json/batch/v1 and ?rest_route=/batch/v1 at your WAF/reverse proxy — both forms must be blocked.| wp2shell.com | original checker & advisory, Searchlight Cyber |
| Hadrian Security — Technical Breakdown | root cause analysis |
This project is licensed under the MIT License — see the LICENSE file for details.
Cybersecurity ILCS · built for internal defensive use
| Use only against WordPress instances you own, or have explicit written authorization to test (e.g. an approved internal VAPT scope). | |
This probe is designed to be non-destructive — it targets a non-existent category ID (0) and stops at the permission-check layer, so no data is ever created, modified, or deleted. | |
| Do not modify the payload (e.g. change the category ID to a real one, or point it at other REST routes) to attempt actual exploitation. Doing so turns this from a detector into a weaponized exploit — which this tool is explicitly not built for and does not support. | |
| Do not publish, redistribute, or run this against systems outside your authorized scope. Unauthorized use against third-party systems may violate the ITE Law (UU ITE) in Indonesia and equivalent computer-misuse laws elsewhere. | |
| Provided as-is, with no warranty. The author and any associated organization accept no liability for misuse, damage, or legal consequences arising from use of this tool. |
| # | Sub-request | Purpose |
|---|
| 0 | POST http://: | Intentionally malformed — triggers the index desync |
| 1 | DELETE /wp/v2/categories/0 | Safe sensor — category ID 0 never exists |
| 2 | POST /wp/v2/block-renderer/core/paragraph | Reference handler used to detect the leak |
| no marker found | INCONCLUSIVE — WAF, API disabled, or non-WordPress |
| Flag | Description |
|---|
targets | One or more base URLs to scan (required) |
--timeout N | Request timeout in seconds (default: 10) |
--no-color | Disable ANSI colors and scan animation |
--raw | Print full raw request/response payload and headers |