CVE-2014-3704: Drupalgeddon SQL Injection Vulnerability
CRITICAL SECURITY WARNING - DRUPALGEDDON: CVE-2014-3704 is one of the most critical vulnerabilities ever discovered in Drupal. It received a perfect 10.0 CVSS score, allows remote, unauthenticated attackers to execute arbitrary SQL commands, and was massively exploited within hours of disclosure. Any Drupal 7 site running versions prior to 7.32 is almost certainly compromised.
Vulnerability Summary
| Attribute |
Details |
| Common Name |
Drupalgeddon |
| CVE Identifier |
CVE-2014-3704 |
| Drupal Advisory |
SA-CORE-2014-005 |
| Vulnerability Type |
SQL Injection (via database abstraction layer) |
| Affected Versions |
Drupal 7.x (all versions before 7.32) |
| Severity (CVSS v3 Base) |
10.0 CRITICAL (CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H) |
| Attack Vector |
Remote, unauthenticated (requires no login) |
| Primary Impact |
Full database control, data theft, PHP code execution, complete site/server compromise |
Technical Description
The vulnerability resides in Drupal 7's Database Abstraction API, specifically in how it handles expanded array arguments in SQL queries through the expandArguments() function in includes/database/database.inc.
When user-supplied input containing specially crafted nested arrays is passed to database queries, the sanitization logic fails to properly escape the content, allowing an attacker to inject arbitrary SQL syntax directly into the generated query. This bypasses Drupal's standard input filtering and prepared statement protections.
How the Exploit Works
- An attacker sends a crafted HTTP request to a vulnerable Drupal site containing malicious array parameters in the query string or POST data.
- These parameters are passed to a database query. Due to the bug, they are not properly sanitized when converted to SQL.
- The malicious input alters the SQL query's structure, allowing the attacker to:
- Add new administrator users by inserting into the
users table.
- Extract sensitive data from any database table (user emails, hashed passwords, private content).
- Execute PHP code by inserting it into fields that get executed (like blocks or PHP input formats).
- Modify or delete any data in the database.
# Example of a vulnerable query pattern in Drupal 7 (simplified)
$query = db_select('users', 'u')
->condition('uid', $input_array) // $input_array is attacker-controlled
->execute();
Attack URL pattern often seen in logs:
/?q=node&destination=node&uid[0][table]=users&uid[0][target]=password&uid[0][value]=1
Mitigation & Patching
Immediate Action: Update or Patch NOW
Option 1: Full Update (RECOMMENDED)
Upgrade to Drupal 7.32 or later. However, note that Drupal 7 reached End-of-Life (EOL) in January 2025 and no longer receives security updates. The long-term solution is migration to Drupal 10+.
# For composer-managed sites
composer update drupal/core --with-dependencies
# For manual updates, download and replace core files from drupal.org
# Always backup your 'sites/' directory and database first.
Option 2: Apply the Emergency Patch (If Update Is Impossible)
- Download the official patch:
wget https://www.drupal.org/files/issues/SA-CORE-2014-005.patch
- Apply it from your Drupal root directory:
cd /path/to/drupal
patch -p1 < SA-CORE-2014-005.patch
- Clear all caches:
drush cache-clear all
Important: The patch is a temporary fix. Due to Drupal 7's EOL status, you must immediately plan a migration to a supported CMS platform.
Temporary Access Restriction
If patching will take time, restrict site access via .htaccess (Apache) or server configuration to only trusted IPs.
# In .htaccess in Drupal root
Order deny,allow
Deny from all
Allow from 203.0.113.10 # Your IP
Allow from 192.168.1.0/24 # Your local network
Detection & Compromise Checks
If your site ran Drupal 7.x before version 7.32, assume it was compromised. Conduct thorough checks:
1. Database Investigation Queries
# Check for suspicious users created around Oct 2014
SELECT uid, name, mail, created, access FROM users WHERE created > '2014-10-14' ORDER BY created DESC;
# Look for PHP code in variables or blocks
SELECT * FROM variable WHERE value LIKE '%<?php%' OR value LIKE '%eval(%';
SELECT * FROM block WHERE body LIKE '%<?php%';
# Check for altered user roles (admin permissions)
SELECT ur.uid, u.name, r.name as role_name FROM users_roles ur JOIN users u ON ur.uid = u.uid JOIN role r ON ur.rid = r.rid WHERE r.name = 'administrator' AND u.created > '2014-10-14';
2. Filesystem Inspection
# Find recently added/modified PHP files in sites/
find /path/to/drupal/sites -name "*.php" -type f -mtime -365 -exec ls -la {} \;
# Look for common backdoor filenames
find /path/to/drupal -type f \( -name "*shell*" -o -name "*b374k*" -o -name "*c99*" -o -name "*r57*" \) 2>/dev/null
3. Web Server Log Analysis
# Search for exploit patterns in Apache/Nginx logs
grep -E "(uid\[.*\]\[table\]|expandArguments|\?q=node.*destination)" /var/log/apache2/access.log
# Look for POST requests to node endpoints with array parameters
grep "POST.*node" /var/log/apache2/access.log | head -20
If you find evidence of compromise:
- Take the site offline immediately.
- Restore from a known-clean backup from BEFORE October 15, 2014.
- Apply the patch or update to a clean version.
- Change all passwords (database, Drupal admin, SSH/FTP).
- Consider the server itself compromised and review other sites/services on it.
Long-Term Prevention
- Stay Updated: Subscribe to Drupal security announcements. For active sites, use a supported CMS version.
- Web Application Firewall (WAF): Deploy a WAF like Cloudflare, Sucuri, or ModSecurity to block SQL injection and other attacks at the network edge.
- Least Privilege Database User: Ensure Drupal's database user has only the necessary permissions (SELECT, INSERT, UPDATE, DELETE on its own database, NOT global privileges).
- Regular Security Scans: Use tools like the Security Review module, Acunetix, or manual penetration testing.
- File Integrity Monitoring: Use tools like AIDE or OSSEC to detect unauthorized file changes.
Exploitation Impact
This vulnerability had unprecedented real-world impact:
- Mass exploitation within 7 hours: The Drupal Security Team famously stated that sites not updated within 7 hours of the announcement should be considered compromised.
- Widespread backdooring: Thousands of sites were infected with cryptocurrency miners, spam bots, redirects to malware, and persistent backdoors.
- Long-lasting legacy: Many unpatched or forgotten sites remained compromised for years, becoming part of botnets.
- Highlighted supply chain risk: Compromised sites were used to distribute malware to visitors through poisoned JavaScript and iframes.
Key Takeaway: CVE-2014-3704 serves as a stark lesson in the critical importance of prompt security updates, the dangers of running end-of-life software, and the necessity of having an incident response plan for when, not if, a critical vulnerability affects your systems.
High-Availability Cloud VDS
- Uptime Р 99.95%
- Network bandwidth Р 1 Gb/s
- Technical support 24/7/365
learn more...