CVE-2026-9082 — Drupal Core SQL Injection Vulnerability

CVE-2026-9082

Drupal Core — Unauthenticated SQL Injection via PostgreSQL EntityQuery Array Key Injection Enables Privilege Escalation and RCE; Fixed 11.3.10 / 10.6.9; 15,000+ Attacks Within Days

What is Drupal Core's Database Abstraction API?

Drupal Core includes a database abstraction layer that wraps PHP's PDO interface, providing a unified API for constructing and executing SQL queries regardless of the underlying database backend (MySQL, MariaDB, PostgreSQL, SQLite). The EntityQuery system is Drupal's high-level query builder for content entities — it translates PHP method chains (like $query->condition('name', $values, 'IN')) into backend-specific SQL. The PostgreSQL backend has its own EntityQuery condition handler that generates SQL placeholders for array conditions by creating identifier names from the array values' keys. This placeholder naming mechanism is the root of CVE-2026-9082: when PHP array keys are attacker-controlled, they can inject SQL into the placeholder identifier string before reaching the database driver.

Overview

CVE-2026-9082 is an unauthenticated SQL injection vulnerability (CWE-89) in Drupal Core's PostgreSQL EntityQuery condition handler, affecting all Drupal 10.x and 11.x installations backed by PostgreSQL. The injection occurs in three files of the database abstraction API when processing IN conditions with PHP associative array input — array keys are concatenated into SQL placeholder names without sanitization, allowing an attacker-controlled key to inject arbitrary SQL. MySQL, MariaDB, and SQLite installations are not affected. Drupal patched the vulnerability on May 20, 2026 (SA-CORE-2026-004) with fixes across all supported branches. CISA added CVE-2026-9082 to the KEV catalog on May 22, 2026 — two days after the patch — after Drupal confirmed active exploitation in the wild.

The NVD CVSS score of 6.5 MEDIUM is widely regarded as an undercount of the practical impact: Drupal's own risk rating is Highly Critical (20/25), reflecting that unauthenticated network exploitation can yield full database read/write access including administrator credentials and a realistic RCE path. The CVSS score reflects only the direct C:L/I:L impact of the SQL injection primitive, not the escalated impact of the exploitation chain.

Affected Versions

PostgreSQL-backed Drupal installations only — MySQL, MariaDB, and SQLite are not affected.

Branch Affected Fixed
Drupal 11.3.x 11.3.0–11.3.9 11.3.10
Drupal 11.2.x 11.2.0–11.2.11 11.2.12
Drupal 11.1.x / 11.0.x All (EOL) 11.1.10 (best-effort)
Drupal 10.6.x 10.6.0–10.6.8 10.6.9
Drupal 10.5.x 10.5.0–10.5.9 10.5.10
Drupal 10.4.x All (EOL) 10.4.10 (best-effort)
Drupal 8.9.x / 9.x All (EOL) Hotfix files only

Technical Details

The SQL injection (CWE-89) resides in three files of Drupal's EntityQuery condition system for PostgreSQL:

  • core/lib/Drupal/Core/Entity/Query/Sql/Condition.php
  • core/lib/Drupal/Core/Entity/Query/Sql/ConditionAggregate.php
  • core/modules/pgsql/src/EntityQuery/Condition.php

When an IN condition is processed with a PHP associative array, the condition handler iterates through the array and builds SQL placeholder identifier names by concatenating the field name with each array key — e.g., "field_name_" . $key. Array keys are never sanitized before entering this concatenation, allowing a malicious key (e.g., ) OR 1=1--) to inject SQL into the placeholder name string that reaches the PostgreSQL driver.

Two unauthenticated exploitation vectors were immediately demonstrated:

Vector 1 — JSON Login Endpoint (POST /user/login?_format=json): The login endpoint accepts a JSON body for the name field. By supplying a JSON object rather than a string, an attacker creates a PHP associative array with attacker-controlled keys. Injecting a divide-by-zero expression into the key (exploiting PostgreSQL's || string concatenation) enables boolean inference: HTTP 500 (division-by-zero error) means the injected condition evaluated true; HTTP 400 (auth failure) means false. This yields a blind boolean-inference SQL injection channel, enabling full database exfiltration at one bit per request.

Vector 2 — JSON:API Filter (GET /jsonapi/node/{bundle}?filter[…][value][INJECTED_KEY]=x): When the JSON:API module is installed (common), filter parameter keys are passed through the EntityQuery system. A single malformed key triggers SQLSTATE[HY093] (invalid parameter number) on a vulnerable server versus a clean HTTP 200 on a patched one — enabling one-shot unauthenticated fingerprinting, and with additional crafting, full data extraction.

The fix is a one-line change per affected file: calling array_values() on the input array before iterating, resetting PHP array keys to sequential integers (0, 1, 2…) and stripping any attacker-supplied key content before it reaches the SQL placeholder name string.

Discovery

CVE-2026-9082 was reported to the Drupal Security Team by Michael Maturi (Google/Mandiant). Proof-of-concept exploits demonstrating both attack vectors were developed and published on May 21, 2026 by Animesh Acharya of Tanto Security (Searchlight Cyber), one day after the advisory — the same day the patch diff was publicly circulating. The Drupal Security Team issued a pre-announcement PSA two days before the advisory (May 18) to alert site owners to prepare for an imminent critical release, consistent with their practice for vulnerabilities rated Highly Critical.

Exploitation Context

CVE-2026-9082 hit an unusually tight exploitation timeline: working proof-of-concept code was available within 24 hours of patching, and confirmed in-the-wild exploitation was reported within 48 hours. Imperva telemetry documented over 15,000 attack attempts targeting approximately 6,000 individual Drupal sites across 65 countries within days of disclosure — consistent with automated mass-scanning to enumerate vulnerable PostgreSQL-backed Drupal installations before site operators applied patches.

Successful exploitation gives an attacker full read/write access to the Drupal PostgreSQL database, including:

  • All user accounts and password hashes — enabling administrator account takeover via offline credential cracking or direct hash replacement
  • All non-public content, private user data, and configuration stored in the database
  • Data modification or deletion, enabling defacement, content injection, or site destruction

Remote code execution is a realistic next step from database access: PostgreSQL's file system access functions (COPY TO/FROM PROGRAM, large object operations) combined with writable web directories or Drupal's file upload paths can achieve OS-level code execution, particularly on misconfigured or shared-hosting deployments.

No specific named threat actor or ransomware group had been publicly attributed to the mass-scanning activity as of the KEV addition date. The rapid PoC-to-exploitation timeline and indiscriminate geographic spread are consistent with opportunistic mass exploitation by automated tooling.

Remediation

  1. Upgrade Drupal immediately — apply the patched release for your branch: 11.3.10, 11.2.12, 11.1.10, 10.6.9, 10.5.10, or 10.4.10. The CISA deadline for U.S. federal agencies is May 27, 2026 (5 days after KEV addition — one of the shortest deadlines in KEV history).
  2. Identify whether your installation uses PostgreSQL — run drush status | grep database or check settings.php for the $databases driver. MySQL, MariaDB, and SQLite installations are not affected by this specific vulnerability.
  3. Treat any pre-patch PostgreSQL Drupal site as compromised — if the site was running a vulnerable version with any public-facing endpoints (login, JSON:API), assume the database was exfiltrated; rotate all database credentials, Drupal administrator passwords, and any secrets stored in the database.
  4. Apply a web application firewall (WAF) rule as a compensating control for sites that cannot patch immediately — rules that detect SQL metacharacters in JSON:API filter keys and login request bodies can block or alert on exploitation attempts.
  5. Audit user accounts — inspect the users and users_field_data tables for unauthorized administrator accounts created after initial exploitation.
  6. Disable the JSON:API module if unused — reduces the attack surface by eliminating Vector 2; the login endpoint (Vector 1) cannot be disabled without breaking authentication.
  7. Monitor access logs — look for POST requests to /user/login?_format=json with unexpected body sizes, and GET requests to /jsonapi/ with filter keys containing SQL metacharacters (parentheses, quotes, double-dash sequences).

Key Details

PropertyValue
CVE ID CVE-2026-9082
Vendor / Product Drupal — Core
NVD Published2026-05-20
NVD Last Modified2026-05-21
CVSS 3.1 Score6.5
CVSS 3.1 VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N
SeverityMEDIUM
CWE CWE-89 find similar ↗
CISA KEV Added2026-05-22
CISA KEV Deadline2026-05-27
Known Ransomware Use No

CVSS 3.1 Breakdown

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
Low
Availability
None

Required Action

CISA BOD 22-01 Deadline: 2026-05-27. Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.

Timeline

DateEvent
2026-05-18Drupal Security Team publishes pre-announcement PSA warning of imminent critical security release
2026-05-20Drupal releases SA-CORE-2026-004 and patched versions across all supported branches; CVE-2026-9082 published to NVD; patch diff circulates publicly within hours
2026-05-21Searchlight Cyber (Tanto Security) publishes full technical writeup with two working proof-of-concept exploits; NVD last modified with CVSS data
2026-05-22Drupal confirms exploit attempts detected in the wild; CISA adds CVE-2026-9082 to the Known Exploited Vulnerabilities catalog
2026-05-27CISA BOD 22-01 remediation deadline for U.S. federal agencies

References

ResourceType
NVD — CVE-2026-9082 Vulnerability Database
CISA KEV Catalog Entry US Government