---
title: "WordPress Pre-Auth RCE (CVE-2026-63030)"
canonical: https://trickest.com/library/wordpress-wp2shell-pre-auth-rce
description: "Check a list of WordPress hosts for the wp2shell pre-auth RCE chain, CVE-2026-63030, by confirming the batch route-confusion SQLi on each one."
---

# WordPress Pre-Auth RCE (CVE-2026-63030)

## Overview

wp2shell is the pre-auth remote code execution chain in WordPress Core: a
route-confusion desync in the REST batch processor (CVE-2026-63030) lets a SQL
injection in the posts endpoint that WordPress normally blocks (CVE-2026-60137)
through. It hit CISA's Known Exploited list within days of the July 2026
disclosure, and it needs no plugins, no configuration, and no login. This
workflow takes a list of WordPress hosts and tells you which of them the chain
actually fires on. It sends the nested-batch payload, confirms the route
confusion by its two error markers, then proves the injection with a calibrated
time oracle rather than assuming a version number is enough. Every host comes
back sorted into exploitable or not, so a fleet-wide advisory turns into an
evidenced fix list for [offensive security](/use-cases/offensive-security).

## Pipeline

1. Read the target list: the WordPress hosts, URLs, or ranges to check.
2. Each target is probed against `/?rest_route=/batch/v1`. The nested-batch
   payload has to return both the `parse_path_failed` and `rest_batch_not_allowed`
   markers, which is the route-confusion desync of CVE-2026-63030; a host missing
   either is recorded as not wp2shell and skipped. The probe runs distributed
   across the fleet, so the whole list is tested in one pass.
3. On a host that shows the markers, the injection is confirmed with a timing
   oracle: a `SLEEP`-based payload through the `author_exclude` parameter is
   calibrated against true and false conditions, and the host counts as
   vulnerable only when the true condition is measurably slower.
4. The per-target results are collected and written to a report with the
   exploitable hosts, the timing evidence, and the fleet vulnerability rate.

## Inputs

- **Target list.** The WordPress hosts to check, as domains or URLs, one per
  line. Point it at scope you are authorised to test.

## Outputs

- **Exploitable host list.** The targets where both the route-confusion markers
  and the blind SQLi fired, separated from the ones that did not.
- **Per-target evidence.** For each host: whether the markers were present,
  whether the SQLi was confirmed, and the calibrated timing that decided it, so
  a finding can be checked rather than taken on trust.
- **Final report.** The exploitable set, the counts, and the vulnerability rate
  across the whole list, in one file you can hand to whoever owns remediation.

## Sample output

Illustrative, in the record shape the workflow emits. Real runs name live hosts,
so the targets here are documentation domains.

Each target comes back with its markers, whether the SQLi was confirmed, and the
timing that decided it. A host that fails the marker check is set aside rather
than probed further:

```jsonl
{"target_url": "http://blog.example.com", "vulnerable": true, "markers_found": true, "sqli_confirmed": true, "detection_detail": "sqli=yes thresh=0.22s true=0.41s false=0.04s", "error": null}
{"target_url": "http://shop.example.com", "vulnerable": true, "markers_found": true, "sqli_confirmed": true, "detection_detail": "sqli=yes thresh=0.19s true=0.38s false=0.03s", "error": null}
{"target_url": "http://www.example.org", "vulnerable": false, "markers_found": false, "sqli_confirmed": false, "detection_detail": "Marker check failed: []", "error": "not_wp2shell"}
{"target_url": "http://news.example.net", "vulnerable": false, "markers_found": true, "sqli_confirmed": false, "detection_detail": "sqli=no thresh=0.21s true=0.05s false=0.04s", "error": null}
```

The final report is the fleet triage in one line:

```json
{"total_targets": 480, "vulnerable": 7, "not_vulnerable": 468, "errors": 5, "vulnerability_rate": 1.5}
```

## FAQ

### What is CVE-2026-63030?

It is a route-confusion logic flaw in the WordPress REST API batch processor
(`/wp-json/batch/v1`), introduced in WordPress 6.9. On its own it desynchronises
the batch validator, and chained with the CVE-2026-60137 SQL injection it becomes
wp2shell, an unauthenticated path to remote code execution. This workflow tests
for the chain rather than describing it, so treat the run output as the authority
on which of your hosts are affected.

### Which WordPress versions are affected?

WordPress 6.9.0 through 6.9.4 and 7.0.0 through 7.0.1, plus the 7.1 betas.
The fix ships in 6.9.5 and 7.0.2. Versions before 6.9 do not have the batch
processor path and are not affected. Because it confirms the flaw by behaviour,
this check does not depend on the version string a host advertises.

### Does it drop a shell, or just detect the flaw?

It confirms exploitability and stops there. It proves the route confusion and the
blind SQL injection with a timing oracle; it does not go on to create an
administrator, upload a plugin, or execute code. The output is evidence that a
host is exploitable, not a compromised host.

### Does it need credentials for the target?

No. The chain is pre-auth, so the check runs exactly as an unauthenticated
attacker would, with no login to the target and no WordPress account.

### Can I run this against a host I do not own?

Run it only against scope you are authorised to test. It sends a real injection
payload to confirm the flaw, which is an intrusive act, not a passive scan.

## Related workflows

- [Scan WordPress for Known CVEs](/library/wordpress-vulnerability-scanner).
  Reach for this instead when you want a WordPress host's full posture, its core
  and plugin versions and known CVEs, rather than a yes or no on this one chain.
- [ASN-Wide Vulnerability Scan](/library/asn-vulnerability-scanner). Reach for this
  when you do not have the host list yet and need to turn an ASN into its live
  hosts before checking any of them.

---
_Markdown source of https://trickest.com/library/wordpress-wp2shell-pre-auth-rce._
