php[architect] logo

Want to check out an issue? Sign up to receive a special offer.

Why you MUST Upgrade to Drupal 7.32, now.

Posted by on October 16, 2014

Are you done updating your nginx and apache servers to no longer support SSLv3 and prevent the POODLE attack? Well, now it’s time to upgrade your Drupal 7 sites to version 7.32, as a significant SQL injection vulnerability has been fixed in that update. Exploits are sure to follow, if they aren’t already in the wild.

SA-CORE-2014-0044

The technical writeup of the exploit is, in my opinion, actually very light in providing technical details. Helpfully, there’s a simple patch to prevent the attack. If you can’t do a full upgrade right now, go apply the patch. The exploit can be used by anonymous attackers, so an ounce of prevention here will pay off. Let’s take a look at the patch:

diff --git a/includes/database/database.inc b/includes/database/database.inc
index f78098b..01b6385 100644
--- a/includes/database/database.inc
+++ b/includes/database/database.inc
@@ -736,7 +736,7 @@ abstract class DatabaseConnection extends PDO {
// 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) {
+ foreach (array_values($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

The fix is to change the foreach loop to ensure it loops through a numerically indexed array of values. Without the call to array_values, malicious attackers could inject SQL conditions via the array’s keys, which are used to name the expanded placeholders. The post on sucuri.net about the exploit shows the manipulated SQL statement. A good discussion of the attack can also be found on the PHP subreddit.

But…PDO?

I was a bit stumped at first. Drupal 7 is using PDO and prepared statements, so it should be safe from SQL injection. Right? Diving into the affected file, this foreach loop is in a function, expandArguments that “supports an alternate syntax for doing arrays of values”. Looking at the example from the advisory:

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.

So, because the array keys were not filtered nor sanitized, attackers can change the resulting SQL. Coupled with the fact that PDO allows multi-queries by default, a single call could execute an insert, update, delete, drop statement along with the original select statement.

Disabling Multipe Queries

Don’t use Drupal? Because PDO uses emulated prepared statements, If you’re using PDO to interact with MySQL, you may want to disable multiple queries in your PDO statements as a safeguard. Though you’ll also lose the ability to “use a named parameter marker of the same name more than once in a prepared statement”. Read the PHP documentation for PDO::prepare, first. To disable it:

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

Security is Ongoing

This attack reinforces that security is hard and ongoing. You can’t trust user input, so remember to always Filter Input, Escape Output (FIEO). Kudos to the Drupal security team for addressing and publicizing the vulnerability. While it’s unfortunate that an exploit was found, it’s comforting to know that the project has a team dedicated to security.


Oscar still remembers downloading an early version of the Apache HTTP server at the end of 1995, and promptly asking "Ok, what's this good for?" He started learning PHP in 2000 and hasn't stopped since. He's worked with Drupal, WordPress, Zend Framework, and bespoke PHP, to name a few. Follow him on Google+.
Tags: ,
 

Leave a comment

Use the form below to leave a comment: