← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-9082 · CWE-89 · Disclosed 2026-05-20

Improper Neutralization of Special Elements used in an SQL Command

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a master key that only fits one brand of lock, but too many front doors still use that lock

CVE-2026-9082 is an unauthenticated SQL injection in Drupal core's database abstraction layer, specifically the PostgreSQL EntityQuery path. The official affected ranges are >= 8.9.0 < 10.4.10, >= 10.5.0 < 10.5.10, >= 10.6.0 < 10.6.9, >= 11.0.0 < 11.1.10, >= 11.2.0 < 11.2.12, and >= 11.3.0 < 11.3.10; Drupal 8.9 and 9.5 received best-effort manual patches because they are already end-of-life. The important catch is that the SQLi path only applies to sites using PostgreSQL, and practical reachability usually depends on JSON:API, Views exposed filters, autocomplete, or custom code feeding user-controlled arrays into EntityQuery::condition().

Vendor 9.8 CRITICAL overshoots the fleet-wide reality because it scores the worst case as if every Drupal site were equally reachable and equally exposed. In practice, the vulnerable population is sharply narrowed by the database backend requirement and route/module preconditions, which is why this lands as HIGH, not CRITICAL, for patch prioritization. What keeps it high anyway is the ugly combination of unauthenticated remote reachability, public PoC material, KEV listing, and observed exploitation attempts within days of disclosure.

"Internet-reachable and exploited, but only the PostgreSQL slice of Drupal is actually on fire."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find a PostgreSQL-backed Drupal target

The attacker starts with internet-exposed Drupal and looks for sites likely to be running affected core branches. Commodity recon is enough here: fingerprint Drupal, then probe endpoints commonly associated with JSON:API or Views. The practical weapon is ordinary HTTP probing plus Drupal fingerprinting rather than a bespoke zero-day framework.
Conditions required:
  • Target Drupal site is reachable from the internet
  • Target runs an affected Drupal core version
  • Target specifically uses PostgreSQL
Where this breaks in practice:
  • A large share of Drupal deployments use MySQL or MariaDB, so the backend requirement immediately shrinks the victim pool
  • Internal-only Drupal apps are out of reach for direct internet exploitation
  • Asset discovery tools can find Drupal, but not reliably infer PostgreSQL from the outside
Detection/coverage: External scanners and EASM platforms can identify Drupal exposure; runZero published guidance for finding Drupal instances, but backend DB type usually requires host-side verification.
STEP 02

Reach the vulnerable request path

The exploit chain needs traffic to flow into the PostgreSQL EntityQuery condition handler with attacker-controlled array keys. Akamai's analysis points to JSON:API, Views exposed filters, and entity autocomplete as realistic paths; the public lab by dinosn/drupal-sa-core-2026-004-lab demonstrates JSON:API-based reproduction. This is still unauthenticated remote, but it is not every URL on every Drupal site.
Conditions required:
  • A vulnerable endpoint is enabled and reachable
  • The request path preserves attacker-controlled array keys into EntityQuery::condition()
  • Anonymous access or a low-privilege path exists to the target content
Where this breaks in practice:
  • Sites without JSON:API, exposed Views filters, autocomplete exposure, or similar custom code are much harder to hit
  • Anonymous access may be restricted on some hardened deployments
  • Reverse proxies or WAFs may already normalize or block suspicious parameter structures
Detection/coverage: DAST and vuln scanners may miss this unless they specifically test associative-array key injection, because the bug lives in parameter structure handling rather than a simple value sink.
STEP 03

Inject through array-key placeholder manipulation

The attacker sends crafted parameters where the array key, not just the value, becomes part of a SQL placeholder name. Tenable and the public reproduction lab both describe the fix as forcing array_values() so attacker-supplied keys are discarded. Public material includes a detection PoC and a reproducible lab, which means defenders should assume exploit adaptation is well within commodity attacker skill.
Conditions required:
  • Request reaches the vulnerable PostgreSQL handler unchanged
  • Application uses array-valued conditions such as IN or NOT IN on reachable fields
  • Input validation does not reject malformed key names
Where this breaks in practice:
  • This is more specialized than classic ' OR 1=1 -- value injection
  • Some probes only produce SQL errors or blind extraction conditions rather than clean interactive exploitation
  • WAF SQLi signatures can catch many metacharacter-heavy payloads if deployed in block mode
Detection/coverage: Good network and app-layer detections exist: Akamai states its SQL injection risk group blocks tested payloads, and the public lab calls out SQLSTATE[HY093] / invalid parameter count errors as a strong indicator.
STEP 04

Turn SQLi into real impact

From SQL execution, the attacker can exfiltrate data, tamper with content, and potentially escalate further depending on database privileges and site configuration. The vendor advisory explicitly says remote code execution is possible in some cases, which matters: RCE is not the default outcome on every box. The most common first-order enterprise impact is likely credential hash theft, session/user manipulation, and application-level database compromise.
Conditions required:
  • Successful SQL injection is achieved
  • Database account has access to sensitive tables
  • For worst-case outcomes, database and app configuration permit follow-on abuse
Where this breaks in practice:
  • OS-level or full application takeover is configuration-dependent, not guaranteed by the bug alone
  • Least-privileged DB roles and separated infrastructure can limit blast radius
  • Blind or error-based extraction may slow down high-value post-exploitation
Detection/coverage: Database audit logs, WAF blocks, unusual JSON:API/Views requests, and app logs with SQLSTATE errors are the most useful telemetry. Host scanners will confirm version exposure but not whether exploitation already happened.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusYes. Drupal raised advisory exploit status, Tenable notes exploit attempts were detected in the wild, and NVD references CISA KEV inclusion.
KEV statusListed in CISA KEV on 2026-05-22; NVD shows due date 2026-05-27 for federal remediation guidance.
Proof-of-concept availabilityPublic PoC/lab exists. Tenable links to dinosn/drupal-sa-core-2026-004-lab on GitHub; it includes a reproduction lab and generic detection PoC.
EPSSUser-supplied EPSS is 0.34652. I did not verify a primary-source percentile during this assessment, so do not overfit on percentile math here.
CVSS and what it missesVendor/CNA score is 9.8 with CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H, which models worst-case unauthenticated remote compromise. Real-world friction lowers priority because the vulnerable population is narrowed by PostgreSQL-only exposure and route/module requirements.
Affected versions>= 8.9.0 < 10.4.10, >= 10.5.0 < 10.5.10, >= 10.6.0 < 10.6.9, >= 11.0.0 < 11.1.10, >= 11.2.0 < 11.2.12, >= 11.3.0 < 11.3.10.
Fixed versionsUpgrade to 10.4.10, 10.5.10, 10.6.9, 11.1.10, 11.2.12, or 11.3.10 as appropriate. Drupal 9.5 and 8.9 rely on manual best-effort patches rather than normal supported releases.
Exposure population realityThis is not all Drupal. Pantheon explicitly states its hosted sites are not affected because Pantheon does not use PostgreSQL; that is a good reminder that the reachable population is materially smaller than the vendor score implies.
Reachable exploit surfacesAkamai calls out JSON:API, Views exposed filters, and entity autocomplete as practical entry paths. The GitHub lab confirms JSON:API-based reproduction and documents the array-key preconditions.
Disclosure and attributionDisclosed 2026-05-20 in SA-CORE-2026-004. Drupal credits Michael Maturi as the reporter.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to HIGH (8.6/10)

The decisive downward pressure is the population filter: this only burns the subset of Drupal running PostgreSQL and exposing the right request paths, so the vendor's blanket 9.8 does not map to most enterprise fleets. It still stays HIGH because the reachable slice is unauthenticated, public exploit material exists, and KEV means attackers are already spending time on it.

HIGH Affected version ranges and fixed releases
HIGH KEV-listed and active exploitation status
MEDIUM How often PostgreSQL + reachable JSON:API/Views conditions exist across a typical enterprise Drupal estate

Why this verdict

  • Downgrade from vendor 9.8: the bug is unauthenticated remote, but only on the PostgreSQL backend. That backend prerequisite implies a much smaller exposed population than 'all Drupal on the internet.'
  • Another downward adjustment: practical exploitation usually needs JSON:API, exposed Views filters, autocomplete, or equivalent custom code to preserve attacker-controlled array keys into EntityQuery::condition(). That means this is not uniformly reachable across every page and route.
  • Kept HIGH, not MEDIUM: KEV listing on 2026-05-22, observed exploit attempts, and a public GitHub lab/PoC erase any comfort you might take from the narrower population. The exposed slice is clearly attractive and already being probed.

Why not higher?

I am not calling this CRITICAL because the real-world victim pool is constrained twice: first by Drupal-on-PostgreSQL, then by the need for a reachable endpoint pattern that preserves attacker-controlled array keys. Also, vendor language says remote code execution is possible only 'in some cases,' so worst-case impact is not the default outcome across all affected hosts.

Why not lower?

I am not dropping this to MEDIUM because the attacker position is still unauthenticated remote and the target class is an internet-facing CMS. Once KEV and public PoC material enter the picture, a narrow-but-real exposed slice deserves front-of-queue handling.

05 · Compensating Control

What to do — in priority order.

  1. Block anonymous access to vulnerable query surfaces — At the reverse proxy or WAF, immediately restrict or block anonymous requests to JSON:API collection endpoints, exposed Views filter routes, and entity autocomplete paths where business impact allows. Because this CVE is KEV-listed, deploy this immediately, within hours, not on the normal HIGH 30-day cycle.
  2. Turn on WAF SQLi blocking — Enable SQL injection signatures in block/deny mode and verify they inspect decoded parameter names, not just values. Akamai reports tested payload coverage for existing SQLi risk groups; for this KEV case, validate and enforce the rule set within hours.
  3. Hunt for probe artifacts — Search web, app, and database logs for SQLSTATE[HY093], invalid parameter count errors, and suspicious filter[...] keys containing metacharacters or SQL fragments. Do this immediately, within hours, because it tells you whether you are merely exposed or already being touched.
  4. Constrain Drupal DB privileges — Review the PostgreSQL role used by Drupal and strip unnecessary rights that could turn SQLi into destructive write access or easier follow-on abuse. This does not fix the bug, but it can reduce blast radius; complete it within hours if you cannot patch at once.
  5. Fence internet exposure — If the affected site is not truly public-facing, put it behind VPN, IP allowlists, or upstream auth until patching is complete. Because exploitation evidence exists, make that exposure decision within hours, not next change window.
What doesn't work
  • EDR alone does not stop the initial SQLi; by the time it sees anything, the database may already be queried or tampered with.
  • WAF in monitor mode is not a compensating control; if you are only logging hits, the attacker still gets to execute the request.
  • Assuming all Drupal is affected wastes time, but the opposite mistake is worse: simply seeing Drupal and dismissing the issue without checking for PostgreSQL and exposed routes leaves real victims uncovered.
06 · Verification

Crowdsourced verification payload.

Run this on the target Drupal host as a user who can read the Drupal codebase and sites/*/settings.php files; root is not required if file permissions allow access. Invoke it with the Drupal docroot, for example: bash verify-cve-2026-9082.sh /var/www/html/web — it checks the installed Drupal core version and whether the site is configured for PostgreSQL, then prints VULNERABLE, PATCHED, or UNKNOWN.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# verify-cve-2026-9082.sh
# Check Drupal core version + PostgreSQL backend for CVE-2026-9082
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -u

DOCROOT="${1:-}"

if [[ -z "$DOCROOT" || ! -d "$DOCROOT" ]]; then
  echo "UNKNOWN - usage: $0 <drupal-docroot>"
  exit 2
fi

VERSION=""
DB_IS_PGSQL="false"

ver_ge() {
  # returns 0 if $1 >= $2
  [[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -n1)" == "$1" ]]
}

ver_lt() {
  # returns 0 if $1 < $2
  [[ "$1" != "$2" ]] && ! ver_ge "$1" "$2"
}

# Try composer.lock first
if [[ -f "$DOCROOT/composer.lock" ]]; then
  VERSION=$(php -r '
    $f=$argv[1];
    $j=json_decode(file_get_contents($f), true);
    if (!is_array($j)) exit(1);
    $pkgs=array_merge($j["packages"] ?? [], $j["packages-dev"] ?? []);
    foreach ($pkgs as $p) {
      if (($p["name"] ?? "") === "drupal/core") {
        $v=$p["version"] ?? "";
        $v=preg_replace("/^v/", "", $v);
        echo $v;
        exit(0);
      }
    }
    exit(1);
  ' "$DOCROOT/composer.lock" 2>/dev/null)
fi

# Fallback to core/lib/Drupal.php constant
if [[ -z "$VERSION" && -f "$DOCROOT/core/lib/Drupal.php" ]]; then
  VERSION=$(grep -E "const VERSION = '" "$DOCROOT/core/lib/Drupal.php" 2>/dev/null | sed -E "s/.*const VERSION = '([^']+)'.*/\1/" | head -n1)
fi

# Detect PostgreSQL from settings.php files
while IFS= read -r -d '' f; do
  if grep -Eqi "['\"]driver['\"]\s*=>\s*['\"]pgsql['\"]|['\"]database['\"]\s*=>\s*['\"]pgsql['\"]" "$f"; then
    DB_IS_PGSQL="true"
    break
  fi
done < <(find "$DOCROOT/sites" -type f -name settings.php -print0 2>/dev/null)

if [[ -z "$VERSION" ]]; then
  echo "UNKNOWN - could not determine Drupal core version"
  exit 2
fi

if [[ "$DB_IS_PGSQL" != "true" ]]; then
  echo "PATCHED - Drupal core $VERSION detected, but no PostgreSQL configuration found for this CVE"
  exit 0
fi

VULN="false"

if ver_ge "$VERSION" "8.9.0" && ver_lt "$VERSION" "10.4.10"; then VULN="true"; fi
if ver_ge "$VERSION" "10.5.0" && ver_lt "$VERSION" "10.5.10"; then VULN="true"; fi
if ver_ge "$VERSION" "10.6.0" && ver_lt "$VERSION" "10.6.9"; then VULN="true"; fi
if ver_ge "$VERSION" "11.0.0" && ver_lt "$VERSION" "11.1.10"; then VULN="true"; fi
if ver_ge "$VERSION" "11.2.0" && ver_lt "$VERSION" "11.2.12"; then VULN="true"; fi
if ver_ge "$VERSION" "11.3.0" && ver_lt "$VERSION" "11.3.10"; then VULN="true"; fi

if [[ "$VULN" == "true" ]]; then
  echo "VULNERABLE - Drupal core $VERSION with PostgreSQL configuration matches CVE-2026-9082 affected ranges"
  exit 1
fi

echo "PATCHED - Drupal core $VERSION with PostgreSQL configuration is outside known affected ranges"
exit 0
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, do not treat this like a generic Drupal 9.8; first identify the PostgreSQL-backed slice of your Drupal estate, then assume any internet-exposed members of that slice are urgent. Because this CVE is KEV-listed and exploitation is observed, the normal timetable is overridden: patch / mitigate immediately, within hours. If you cannot patch in the same business day, apply route blocking/WAF deny rules and exposure fences within hours as the temporary control. For recordkeeping, the noisgate mitigation SLA override here is immediate action due to KEV, while the noisgate remediation SLA for a HIGH finding is <= 180 days—but for internet-facing PostgreSQL Drupal, that is an outer limit, not an acceptable target date.

Sources

  1. Drupal advisory SA-CORE-2026-004
  2. NVD CVE detail
  3. CISA KEV catalog
  4. Tenable analysis
  5. Akamai technical analysis
  6. runZero exposure guidance
  7. Pantheon platform note
  8. Public GitHub lab / detection PoC
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.