If you run WordPress, this one’s a must-read. A couple of weeks ago, a critical vulnerability chain called wp2shell dropped, and it’s the real deal — unauthenticated remote code execution on a default WordPress install. No plugins required. No special configuration. Just a vanilla WordPress site and you’re in.
What is wp2shell?
wp2shell is not a single bug — it’s a chain of two CVEs discovered by Adam Kues from Searchlight Cyber / Assetnote. Together, they turn a REST API routing quirk into a full SQL injection, then into a new admin account, and finally into a webshell on your server.
The vulnerabilities affect WordPress 6.9.0 through 6.9.4, and 7.0.0 through 7.0.1. Patched in 6.9.5 and 7.0.2.
The Two CVEs
CVE-2026-63030 — REST API Batch Route Confusion (CVSS 8.8)
WordPress ships a /wp-json/batch/v1 endpoint that processes multiple sub-requests in one go. The bug is in serve_batch_request_v1() — it builds parallel arrays for route matching and permission validation, but when a sub-request fails silently, the arrays desync. Every sub-request after that point gets paired with the wrong route’s authentication state. This lets an attacker sneak an unauthenticated request past the permission check.
CVE-2026-60137 — SQL Injection via author__not_in (CVSS 9.8)
With the route confusion bypassing auth, the attacker can reach WP_Query’s author__not_in parameter. When supplied as a scalar string (not an array), it gets interpolated directly into raw SQL. No sanitization. No parameterised query. Just straight injection into a WHERE clause.
The Attack Chain
Here’s how it works end-to-end:
- Attacker sends a crafted POST to
/wp-json/batch/v1with a nested batch payload - The inner batch triggers the desync condition — the second sub-request slips through without auth
- That sub-request hits
/wp/v2/postswith a maliciousauthor__not_inparameter - The parameter is injected into raw SQL, giving the attacker a read/write SQLi primitive
- The attacker extracts admin password hashes, creates a new admin account, or writes a webshell via MySQL
INTO OUTFILE - Full site takeover, potentially with persistent access
Why It’s Bad
This isn’t a niche plugin bug. It’s in WordPress core. Every unpatched WordPress site is a target. And since CISA added it to the Known Exploited Vulnerabilities catalog on July 21, 2026, and a public PoC hit GitHub the next day, the window for proactive patching is long gone. Mass scanning is already happening.
Detection
The 0xsha variant of the exploit includes a non-destructive check that uses a structural signal — if the batch desync causes a block_cannot_read error from the block-renderer’s permission callback on a POST request, you’re vulnerable. No data is modified, no rows touched.
Remediation
- Update to WordPress 6.9.5 or 7.0.2 immediately
- Don’t rely on automatic background updates — verify explicitly
- Check for unexpected admin accounts or suspicious files in
wp-content/uploads/ - Review
wp-config.phpforDISALLOW_FILE_EDITandDISALLOW_FILE_MOD - If you suspect compromise, rotate all credentials and audit user registrations
PoC & References
Links to the public PoC and the best technical writeups I’ve found:
- Icex0/wp2shell-poc — Full RCE chain PoC (independent implementation)
- 0xsha/wp2shell — Non-destructive detector + check script
- dinosn/wp2shell-lab — Docker lab for testing
- Wiz Blog — In-the-wild exploitation analysis
- Eye Research — Incident response guide
- Elastic Security Labs — Detection rules and IOCs
Patch now. Don’t wait. If you’re running WordPress, assume you’re being scanned right now.