A critical, unauthenticated SQL injection in Drupal Core is on CISA's Known Exploited Vulnerabilities catalog, which means it is being exploited in the wild right now. If you run Drupal, the honest triage is short: confirm your version, patch today, and, if the site was ever internet-facing while vulnerable, work it as an incident rather than a patch. I have cleaned up after enough Drupal compromises to have stopped assuming the patch alone is the end of it.
Identifying the exact advisory. Drupal tracks core security issues as SA-CORE-YYYY-NNN advisories, each mapped to a CVE. Match your running version against Drupal's official security advisories and the corresponding KEV entry to confirm the precise identifier and fixed version for your branch, the remediation below applies regardless of which specific SA-CORE advisory you are exposed to. The mechanics in this article use the canonical Drupal Core SQLi, CVE-2014-3704 ("Drupalgeddon", SA-CORE-2014-005) as the worked example because it remains the clearest illustration of how these flaws work.
Vulnerability Overview
The flaw affects Drupal Core and allows unauthenticated attackers to execute malicious SQL against vulnerable sites. Depending on site configuration and database permissions, successful exploitation can lead to unauthorised access to sensitive data, authentication bypass, administrative account compromise, remote code execution in chained attacks, and full site takeover. Because it is remotely exploitable without credentials, and Drupal powers a large share of government and enterprise sites, CISA's KEV listing means federal agencies must remediate within a strict deadline, and everyone else should treat it with the same urgency.
Affected Software
- Supported Drupal 10.x releases below the fixed version in the advisory
- Drupal 9.x (now end-of-life, a compounding risk)
- Older, unsupported releases, which frequently remain vulnerable to multiple historical flaws
Verify your exact version immediately and compare it against Drupal's official security advisory for your branch.
Severity
| Attribute | Value |
|---|---|
| Vulnerability class | SQL injection (CWE-89) |
| Attack vector | Network, remote |
| Authentication | None required |
| Typical CVSS band | Critical (9.0–10.0) |
| Exploitation status | Active, KEV-listed |
How a Core-level SQLi actually works
SQL injection happens when user input reaches a query without parameterisation and the attacker gets to rewrite the query's logic. Drupal ships a database abstraction layer built specifically to stop that, which is why I take a SQLi in Core more seriously than one in a contrib module: it breaks the layer every other line of Drupal code assumes is safe.
The archetype is still Drupalgeddon (CVE-2014-3704), and it is worth understanding because modern Core SQLi advisories keep the same shape. Drupal's expandArguments() built IN-clause placeholders from array keys in the request. Those keys were attacker-controlled and never sanitised as identifiers, so a crafted array in the pre-auth login form's name parameter injected arbitrary SQL:
# Drupalgeddon (CVE-2014-3704), attacker-controlled array KEYS become SQL
POST /?q=node&destination=node HTTP/1.1
Content-Type: application/x-www-form-urlencoded
name[0%20;UPDATE+users+SET+pass%3D...+WHERE+uid%3D1;;]=admin&name[0]=admin
&pass=x&form_id=user_login_blockThe takeaway is not the specific payload, it is the pattern: a Core-level input-handling flaw turns an unauthenticated form field into arbitrary SQL, from which an attacker can create an administrator, extract password hashes, or stage code execution. Modern Drupal Core SQLi advisories follow the same shape even when the vulnerable function differs.
Why this class is so punishing on a CMS
Because Drupal is database-integrated to its core, a SQLi hands an attacker the ability to dump the database, pull password hashes, create an admin account, rewrite content, and stage a payload for code execution. These have historically been among the worst bugs the project has shipped, and the response window is brutal: after Drupalgeddon, mass exploitation started within hours, and Drupal's own security team told people that sites not patched within seven hours should be treated as compromised. I have never seen that timeline get more forgiving.
What the exploitation actually looks like
CISA confirmed active exploitation before a lot of organisations had patched, which is normal for Drupal. Internet-facing instances are trivially fingerprinted, patch cycles lag, exploit kits show up fast, and a compromised CMS is easy money, defacement, SEO spam, malware and phishing hosting, or a quiet pivot inward. Assume automated scanners found your site within hours of the disclosure, not days.
Checking whether you're exposed
Get the installed Drupal Core version and compare it to the advisory for your branch:
# If you use Drush
drush status | grep -i "drupal version"
# Or read it directly
grep "'version'" core/lib/Drupal.php
grep '"drupal/core"' composer.json composer.lockThen confirm whether the fixed release has been applied, and inventory every internet-facing Drupal instance, including forgotten staging and legacy sites, which are the ones that get breached.
Indicators of Compromise
Inspect logs for suspicious POST requests, unusual SQL activity, unexpected administrator account creation, unknown scheduled tasks, modified PHP files, webshell indicators, and outbound connections to unfamiliar IPs. Common webshell filenames dropped after Drupal compromise include shell.php cmd.php adminer.php and cache.php. Check recently modified files under:
/sites/default/files/
/modules/
/themes/
Detection Example
A basic access-log hunt for SQLi patterns and post-exploitation:
# SQL keywords and functions in requests
grep -Ei "union(\s|\+|%20)+select|concat\(|sleep\(|updatexml|extractvalue" access.log
# Suspicious writes to the files directory (possible webshell drop)
find sites/default/files -name "*.php" -newermt "-7 days" -printLook for SQL keywords in URL or POST parameters, encoded payloads, unusually large POST bodies to /user/login or form endpoints, and unexpected database errors in the logs.
Remediation, in priority order
- Patch immediately. Apply the fixed release for your branch:
composer update drupal/core-recommended --with-all-dependencies drush updatedb # apply any pending DB updates drush cache:rebuild - Restrict administrative access. Enforce MFA, limit admin interfaces by IP, and disable unused accounts.
- Deploy or tune a WAF. A properly configured WAF (including Cloudflare's managed Drupal rules) can block common exploitation attempts as a stopgap, not a substitute for patching.
- Audit logs web server, database, authentication events, and file-integrity monitoring.
- Rotate credentials if compromise is suspected: admin passwords, the database credentials, and any API keys or secrets stored in
settings.php. - Hunt for persistence webshells, rogue admin accounts, cron jobs, and modified modules or themes. Assume that a site exposed while vulnerable may already be compromised.
If it was internet-facing and unpatched, assume breach. For actively exploited CMS flaws, patching closes the door but does nothing about an attacker who already walked through it. Preserve logs, hunt for the persistence above, and rotate secrets. A structured triage, the kind packaged in the Incident Response Runbook keeps that process from being improvised at 2 a.m.
Recommended Security Practices
- Keep Drupal Core and all contributed modules updated; subscribe to Drupal security advisories.
- Remove unused modules and themes to shrink the attack surface.
- Use a least-privilege database account, the web app rarely needs
DROPorFILEprivileges. - Enforce MFA on all administrative accounts.
- Segment CMS infrastructure so a web compromise cannot pivot to internal systems.
- Continuously monitor logs and deploy EDR on hosting servers.
References & Further Reading
- Drupal Security Advisories (SA-CORE) the authoritative source for affected versions and fixes.
- CISA Known Exploited Vulnerabilities Catalog.
- NVD: CVE-2014-3704 (Drupalgeddon) the canonical Drupal Core SQLi and the mechanism worked through above.
Frequently Asked Questions
What is the Drupal Core SQL injection vulnerability?
It is a flaw in Drupal Core's input handling that allows an unauthenticated attacker to inject SQL into database queries, potentially extracting data, bypassing authentication, creating admin accounts, or achieving code execution. Drupal publishes these as SA-CORE advisories mapped to CVEs; the canonical example is CVE-2014-3704 (Drupalgeddon), where attacker-controlled array keys in the login form were turned into SQL.
How do I check if my Drupal site is affected?
Determine your exact Drupal Core version with drush status or by reading core/lib/Drupal.php and composer.lock then compare it against Drupal's official security advisory for your branch. Also inventory every internet-facing instance, including staging and legacy sites.
How do I fix it?
Update to the fixed release with composer update drupal/core-recommended --with-all-dependencies run drush updatedb and drush cache:rebuild then restrict admin access, deploy or tune a WAF, and audit logs. If the site was internet-facing while vulnerable, assume compromise and hunt for webshells and rogue admin accounts.
My site was exposed before I patched. Am I compromised?
Possibly. Actively exploited Drupal SQLi flaws are targeted by automated scanners within hours of disclosure, and patching does not remove an attacker who already gained access. Preserve logs, hunt for persistence (webshells, rogue admins, cron jobs, modified modules), and rotate admin, database, and API credentials.
Where I'd leave it
A KEV-listed, unauthenticated SQLi in Drupal Core is about as urgent as web bugs get: remote, trivially automated, and in front of real data. Pin your exact version and advisory, patch today, and if the site was exposed while vulnerable, run the IR steps instead of hoping. The line I keep coming back to on CMS work: the patch stops the bleeding, the hunt is what tells you whether anyone was already inside.