SQL Injection in Drupal Core

A day after Drupal's emergency patches landed, security researchers at Searchlight Cyber have published a full technical breakdown of CVE-2026-9082 — complete with two working proof-of-concept exploits. If your PostgreSQL-backed Drupal site isn't patched yet, consider this the final warning.

Drupal's database abstraction API exists for one reason: to sanitise queries and prevent SQL injection. The flaw is inside that very layer — specifically in the PostgreSQL-specific override that handles case-insensitive comparisons.

Researcher at Searchlight Cyber shows that PostgreSQL is case-sensitive by default, so Drupal wraps query comparisons in a LOWER() function to normalise them. When processing an IN (...) list — say, matching a username against multiple values — it loops through each value and builds SQL placeholder names by combining a field prefix with an array key. The assumption was that those keys would always be sequential integers (0, 1, 2). They aren't.

If an attacker sends a JSON object instead of a plain string for the name field on the login endpoint, PHP decodes it into an associative array with attacker-controlled keys. Those keys land directly inside the SQL text before PDO (PHP's database layer) ever gets to bind and sanitise them. The fix? Three array_values() calls across three files — roughly seven lines of code — that forcibly reset array keys to sequential integers before they reach the vulnerable loop.

Two Entry Points, Both Unauthenticated

Researchers confirmed two separate paths to trigger the injection:

Variant 1 — JSON Login endpoint (/user/login?_format=json): An attacker sends the name field as a JSON object with an injected key containing a divide-by-zero subquery. When the boolean predicate is true, the server returns HTTP 500 with a SQLSTATE[22012] division-by-zero error. When false, it returns HTTP 400. That clean status-code split means an attacker can extract arbitrary database content one bit at a time — at scanning speeds. No session, no CSRF token, no credentials required.

Variant 2 — JSON:API filter parameters (/jsonapi/node/{bundle}): A single GET request with a backtick in a filter key is enough to produce a SQLSTATE[HY093] error on a vulnerable host. This variant doesn't even need a POST body — it's a one-shot fingerprinting probe that works against any publicly accessible node bundle. JSON:API isn't enabled by default, but it's a standard addition on API-driven Drupal deployments.

What's Actually at Risk

Both exploit variants are fully anonymous — no account needed. On a vulnerable PostgreSQL-backed site, an attacker can quietly extract usernames, password hashes, private content, and any other data the database user can access. From there, privilege escalation and remote code execution are realistic next steps depending on the site configuration.

MySQL and SQLite installations are not reachable via these specific paths, but the same Drupal release bundle includes Symfony and Twig security fixes that apply to every backend — so there's no justification for skipping the update.

What You Should Do Right Now

With working exploits now public, automated scanning of Drupal installations has almost certainly already begun. The patch window is effectively closed.