summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathaniel Catchpole2014-10-15 17:39:53 +0100
committerNathaniel Catchpole2014-10-15 17:39:53 +0100
commit19b32a3ab40e8c89495ee260e46a5e8375ad3756 (patch)
tree576a891960caac060a7f0fceeb2c1fba202aa788
parent5564d2cd946ba3a9a16ec495377f04cdd94ce947 (diff)
Issue #2357249 by Stefan Horst, greggles, larowlan, David_Rothstein, klausi: Fixed SA-CORE-2014-005 (SQL injection).8.0.0-beta2
-rw-r--r--core/lib/Drupal/Core/Database/Connection.php2
-rw-r--r--core/modules/system/src/Tests/Database/QueryTest.php30
2 files changed, 31 insertions, 1 deletions
diff --git a/core/lib/Drupal/Core/Database/Connection.php b/core/lib/Drupal/Core/Database/Connection.php
index 7cbe167..e0c1714 100644
--- a/core/lib/Drupal/Core/Database/Connection.php
+++ b/core/lib/Drupal/Core/Database/Connection.php
@@ -596,7 +596,7 @@ abstract class Connection implements \Serializable {
// 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
diff --git a/core/modules/system/src/Tests/Database/QueryTest.php b/core/modules/system/src/Tests/Database/QueryTest.php
index ddfd1a5..964253e 100644
--- a/core/modules/system/src/Tests/Database/QueryTest.php
+++ b/core/modules/system/src/Tests/Database/QueryTest.php
@@ -7,6 +7,8 @@
namespace Drupal\system\Tests\Database;
+use Drupal\Core\Database\DatabaseExceptionWrapper;
+
/**
* Tests Drupal's extended prepared statement syntax..
*
@@ -21,4 +23,32 @@ class QueryTest extends DatabaseTestBase {
$this->assertEqual(count($names), 3, 'Correct number of names returned');
}
+
+ /**
+ * Tests SQL injection via database query array arguments.
+ */
+ public function testArrayArgumentsSQLInjection() {
+ // Attempt SQL injection and verify that it does not work.
+ $condition = array(
+ "1 ;INSERT INTO {test} SET name = 'test12345678'; -- " => '',
+ '1' => '',
+ );
+ try {
+ db_query("SELECT * FROM {test} WHERE name = :name", array(':name' => $condition))->fetchObject();
+ $this->fail('SQL injection attempt via array arguments should result in a database exception.');
+ }
+ catch (DatabaseExceptionWrapper $e) {
+ $this->pass('SQL injection attempt via array arguments should result in a database exception.');
+ }
+
+ // Test that the insert query that was used in the SQL injection attempt did
+ // not result in a row being inserted in the database.
+ $result = db_select('test')
+ ->condition('name', 'test12345678')
+ ->countQuery()
+ ->execute()
+ ->fetchField();
+ $this->assertFalse($result, 'SQL injection attempt did not result in a row being inserted in the database table.');
+ }
+
}