Table Of Contents

Drupal 7 vulnerable to SQL Injection

The worlds third most highly used CMS and web development platform is vulnerable to a SQL Injection which can leave the sites operating on Drupal wide open to hacking attacks. This was notified via a advisory by SektionEins GmbH who have asked all the Drupal users that run Drupal 7 to upgrade to 7.32 to guard against possible attack.

CVE-2014-3704 vulnerability in Drupal 7

The CVE-2014-3704 vulnerability in Drupal 7 has, unsurprisingly, been classified as “highly critical” by SektionEins GmbH. As per their blog, the users of Drupal have to do the patching sooner than later because the easy-to-exploit vulnerability hands over total control.  Once the vulnerability is exploited they can inject malware payload and further their sinister designs to other users visiting the users Drupal site.

“A malicious user can inject arbitrary SQL queries… This vulnerability can be exploited by remote attackers without any kind of authentication required,” an advisory by SektionEins, the German security firm that discovered the flaw, warns.

The vulnerability comes from an API specifically designed to help prevent against SQLi attacks against the open source content management system.  Drupal 7 includes a database abstraction API to ensure that queries executed against the database are sanitized to prevent SQL injection attacks.

A vulnerability in this API allows an attacker to send specially crafted requests resulting in arbitrary SQL execution. Depending on the content of the requests this can lead to privilege escalation, arbitrary PHP execution, or other attacks.


Drupal uses prepared statements in all its SQL queries. To handle IN
statements there is an expandArguments function to expand arrays.

protected function expandArguments(&$query, &$args) {
$modified = FALSE;

// If the placeholder value to insert is an array, assume that we need
// to expand it out into a comma-delimited set of placeholders.
foreach (array_filter($args, ‘is_array’) as $key => $data) {
$new_keys = array();
foreach ($data as $i => $value) {
// This assumes that there are no other placeholders that use the same
// name. For example, if the array placeholder is defined as :example
// and there is already an :example_2 placeholder, this will generate
// a duplicate key. We do not account for that as the calling code
// is already broken if that happens.
$new_keys[$key . ‘_’ . $i] = $value;

// Update the query with the new placeholders.
// preg_replace is necessary to ensure the replacement does not affect
// placeholders that start with the same exact text. For example, if the
// query contains the placeholders :foo and :foobar, and :foo has an
// array of values, using str_replace would affect both placeholders,
// but using the following preg_replace would only affect :foo because
// it is followed by a non-word character.
$query = preg_replace(‘#’ . $key . ‘\b#’, implode(‘, ‘, array_keys($new_keys)), $query);

// Update the args array with the new placeholders.
$args += $new_keys;

$modified = TRUE;

return $modified;

The function assumes that it is called with an array which has no keys. Example:

db_query(“SELECT * FROM {users} where name IN (:name)”, array(‘:name’=>array(‘user1′,’user2’)));

Which results in this SQL Statement

SELECT * from users where name IN (:name_0, :name_1)

with the parameters name_0 = user1 and name_1 = user2.

The Problem occurs, if the array has keys, which are no integers. Example:

db_query(“SELECT * FROM {users} where name IN (:name)”, array(‘:name’=>array(‘test — ‘ => ‘user1′,’test’ => ‘user2’)));

this results in an exploitable SQL query:

SELECT * FROM users WHERE name = :name_test — , :name_test AND status = 1

with parameters :name_test = user2.

Since Drupal uses PDO, multi-queries are allowed. So this SQL Injection can
be used to insert arbitrary data in the database, dump or modify existing data
or drop the whole database.

With the possibility to INSERT arbitrary data into the database an
attacker can execute any PHP code through Drupal features with callbacks.

SektionEins has said that they cant reveal the PoC as they have been asked by Drupal not to.

If you are a Drupal user, you are requested to upgrade your Drupal 7 to Drupal 7.32 at ASAP