Drupal Core CVE-2026-9082: PostgreSQL SQL Injection → RCE (Anonymous Exploitation)

Share
Drupal Core CVE-2026-9082: PostgreSQL SQL Injection → RCE (Anonymous Exploitation)
Drupal Core CVE-2026-9082: PostgreSQL SQL Injection

The Vulnerability: What's Broken

Drupal has a database abstraction API that sits between your application code and the database. Its job is to validate queries and prevent SQL injection. Someone found a flaw in that validation layer that allows crafted requests to bypass the sanitization and inject arbitrary SQL into PostgreSQL databases.

What this means: If you're running Drupal on PostgreSQL and someone sends a specially crafted request to your site, they can run SQL commands they shouldn't be able to. From there, they can read sensitive data, escalate privileges, or achieve remote code execution.

Anonymous users can do this. You don't need to be logged in!


Impact Assessment

PostgreSQL sites: Fully vulnerable if running unpatched versions.

MySQL/MariaDB sites: Not affected. The vulnerability is specific to PostgreSQL's query handling.

What an attacker can do:

  • Information disclosure: Read user data, configuration, private content
  • Privilege escalation: Gain admin-level access
  • Remote code execution: Execute code on the server (depends on PostgreSQL configuration and Drupal setup)
  • Data manipulation: Modify or delete content

The severity depends on your PostgreSQL configuration. If PostgreSQL is set up to allow arbitrary file system access via SQL functions (not recommended but happens), RCE is immediate. Otherwise, information disclosure is the primary risk, but privilege escalation is often the stepping stone to RCE.


Who's Affected

Drupal versions with the flaw:

  • Drupal 11.3.x (before 11.3.10)
  • Drupal 11.2.x (before 11.2.12)
  • Drupal 11.1.x (EOL—patches available as best effort)
  • Drupal 11.0.x (EOL—no patches)
  • Drupal 10.6.x (before 10.6.9)
  • Drupal 10.5.x (before 10.5.10)
  • Drupal 10.4.x (EOL—no patches)
  • Drupal 10.3.x and earlier (EOL—no patches)
  • Drupal 9.x (EOL—manual patches for 9.5 available as best effort)
  • Drupal 8.x (EOL—manual patches for 8.9 available as best effort)
  • Drupal 7: Not affected

Real-world risk: If you're running Drupal on PostgreSQL and haven't patched since May 21, 2026, assume you're exposed.


Patching Strategy

If You're on a Supported Branch

This is straightforward. Update to the patched version:

Drupal 11.3.x:

composer update drupal/core drupal/core-composer-scaffold drupal/core-project-message
# Should pull 11.3.10 or later

Drupal 11.2.x:

composer require drupal/core:~11.2.12

Drupal 10.6.x:

composer require drupal/core:~10.6.9

Drupal 10.5.x:

composer require drupal/core:~10.5.10

After updating, run:

drush updatedb
drush cache:rebuild

Verify the patch was applied:

grep "version" web/core/lib/Drupal.php | head -1

Should show the patched version number.

If You're on an Older or EOL Branch

Drupal 11.1.x, 11.0.x, 10.4.x and below: End-of-life. No official patches. Drupal recommends upgrading to a supported branch. Options:

Option A: Upgrade to Latest Supported (recommended)

  • Drupal 11.3.x (LTS candidate for long-term support)
  • Drupal 10.6.x (security support until mid-2027)

This requires planning and testing. Can't be done in 5 minutes on production.

Option B: Apply Manual Patches (temporary bridge)

  • Drupal provides patches for 9.5 and 8.9 (both EOL) as "best effort"
  • These are emergency patches, not part of regular support
  • The underlying versions still have other unpatched vulnerabilities

If you're stuck on EOL and can't upgrade immediately, get the patch and apply it, but prioritize upgrading to a supported version.

Option C: Network Segmentation (not a fix, but a stopgap)

  • Restrict access to your Drupal site to trusted IPs only
  • Use WAF rules to block suspicious SQL patterns
  • ⚠️ This doesn't fix the vulnerability, just reduces exposure window

Understand the Risk of EOL Versions

Drupal 8 and 9 are end-of-life. They won't receive security patches anymore (except these emergency ones). Running EOL versions means:

  • This vulnerability will eventually be patched by someone, but it won't be official
  • Other vulnerabilities will never be patched
  • You're relying on the community or third-party services for security
  • Dependency versions (Symfony, Twig, etc.) are frozen and may have known vulns

If you're on 8 or 9, treat the upgrade to 10 or 11 as urgent, not optional.


Why This Advisory Includes Symfony/Twig Updates

The patched versions also include upstream security updates for Symfony and Twig. This is important because:

  • Symfony and Twig are core dependencies for Drupal
  • Vulns in those libraries directly affect Drupal security
  • Bundling updates reduces testing overhead (you test once, multiple things are fixed)

If you're on Drupal 11.3, 11.2, 10.6, or 10.5, make sure you get the latest patch version (not just the base .x release).


Detection: How to Spot Exploitation

Look for these patterns in logs:

Access logs (access.log, error.log):

  • Unusual query parameters with SQL syntax (UNION, SELECT, etc.)
  • Requests with --, /*, */, or %2D%2D (SQL comment syntax)
  • POST bodies containing encoded SQL keywords
grep -i "union\|select\|insert\|update\|delete\|drop" /var/log/apache2/access.log | head -20

Drupal database logs:

# If you haven't been fully compromised, check watchdog logs
drush watchdog:list | grep -i error | head -20

PostgreSQL audit logs (if you have them enabled):

# Look for unexpected queries from the Drupal user
sudo -u postgres psql -d your_db -c "SELECT query FROM pg_stat_statements WHERE query ILIKE '%UNION%' OR query ILIKE '%DROP%' LIMIT 20;"

System-level indicators:

  • New user accounts in Drupal admin
  • Modified files in sites/default (theme/module changes)
  • Unusual database user activity
  • New cron jobs or scheduled tasks

If you find any of these, assume you've been compromised. Change all database passwords, rotate API keys, and audit user permissions immediately.


Forensics If You Think You're Compromised

  1. Don't panic and don't restart anything yet. Log files may be your only evidence.
  2. Collect evidence:
   # Dump recent access logs
   tail -n 10000 /var/log/apache2/access.log > /tmp/access_dump.txt
   
   # Dump Drupal watchdog
   drush watchdog:list --extended > /tmp/drupal_watchdog.txt
   
   # Check for modified files
   find web -type f -mtime -1 | grep -E "\.(php|module|theme)" > /tmp/recent_changes.txt
  1. Check database for backdoors:
   # Look for new admin users created recently
   drush user:list | grep -v "Anonymous\|admin"
   
   # Check for suspicious modules installed
   drush pm:list | grep -v "enabled by core"
  1. Review PostgreSQL logs:
   sudo tail -f /var/log/postgresql/postgresql.log | grep -i "error\|warning"
  1. If you find evidence of exploitation: Isolate the server immediately, collect all logs, and escalate to your security team or incident response.

Post-Patch Verification

After applying patches:

  1. Test the site:
   drush status
   # Should show "successful" for database connection
  1. Run automated tests (if you have them):
   composer test
  1. Check for malicious changes:
   # Compare file hashes to known good versions (if you have them)
   find web/core -type f -name "*.php" | md5sum | sort > /tmp/core_hashes_new.txt
   diff /tmp/core_hashes_old.txt /tmp/core_hashes_new.txt
  1. Monitor logs for the next 24 hours: Watch for exploitation attempts or post-compromise activity.

Why PostgreSQL?

PostgreSQL's query parser is stricter than MySQL. This vulnerability exploits that strictness—specifically how Drupal's database API constructs parameterized queries for PostgreSQL.

MySQL sites aren't vulnerable because MySQL handles the same query construction differently. Drupal's existing safeguards work for MySQL but not for PostgreSQL.

This is a good reminder to test database-specific code paths. It's easy for vulnerabilities to hide in vendor-specific code.


Long-Term Recommendation

  1. Upgrade to Drupal 11 if you haven't already. Drupal 10 support ends mid-2027.
  2. Consider Drupal 11.3.x as your LTS target. It'll be supported longer.
  3. Set up automated patching. Use Dependabot or similar tools to get notified of security updates automatically.
  4. Test patches in staging first, but don't delay production deployment for security patches.
  5. Document your Drupal version and dependencies. Makes future upgrades easier.

References

  • Drupal Security Advisory SA-CORE-2026-004
  • CVE-2026-9082 (CVE.org)
  • Drupal Core changelog
  • PostgreSQL documentation
  • Drupal upgrade path documentation