⚠ This tool is created solely for educational or bug bounty purpose only. Unauthorized use outside of controlled environments is strictly prohibited.
Proof-of-concept for the wp2shell vulnerability chain affecting WordPress Core, combining CVE-2026-63030 and CVE-2026-60137. The project demonstrates the interaction between the REST API Batch route confusion vulnerability and a WP_Query SQL injection, resulting in an unauthenticated path to full WordPress compromise and remote code execution (RCE).
Read the full advisory here
wp2shell is a pre-authentication RCE chain in WordPress core, combining CVE-2026-63030 (route confusion in the batch REST endpoint) and CVE-2026-60137 (SQL injection in WP_Query).
The route confusion: /wp-json/batch/v1 processes multiple sub-requests via parallel $matches and $validation arrays indexed by position. A sub-request with a malformed path (e.g., http://:) is appended to $validation but not $matches due to a continue statement, desynchronizing the arrays. Later requests are dispatched under the handler meant for the next request, bypassing schema validation and permission checks.
The SQL injection: Two nested batch calls exploit this. The outer batch bypasses the method allow-list (normally blocking GET). The inner batch delivers a scalar author_exclude string to GET /wp/v2/posts - the desync routes it past validation, and WP_Query interpolates the unsanitized string directly into SQL, yielding a UNION-based blind injection.
Cache poisoning: The SQLi returns forged WP_Post objects, which WordPress caches in-memory. These fake posts contain [embed] shortcodes that cause WordPress to create real oembed_cache database rows from the fake references.
Changeset escalation: Using the SQLi, the attacker forges a customize_changeset post in-memory with "user_id": 1 in its JSON. A cycle-detection gadget triggers wp_update_post() without overwriting post_content, preserving the attacker's payload. Applying the changeset temporarily assumes the administrator's identity.