You are here

public function QueryTest::testConditionOperatorArgumentsSQLInjection in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 core/modules/system/src/Tests/Database/QueryTest.php \Drupal\system\Tests\Database\QueryTest::testConditionOperatorArgumentsSQLInjection()

Tests SQL injection via condition operator.

File

core/modules/system/src/Tests/Database/QueryTest.php, line 72
Contains \Drupal\system\Tests\Database\QueryTest.

Class

QueryTest
Tests Drupal's extended prepared statement syntax..

Namespace

Drupal\system\Tests\Database

Code

public function testConditionOperatorArgumentsSQLInjection() {
  $injection = "IS NOT NULL) ;INSERT INTO {test} (name) VALUES ('test12345678'); -- ";

  // Convert errors to exceptions for testing purposes below.
  set_error_handler(function ($severity, $message, $filename, $lineno) {
    throw new \ErrorException($message, 0, $severity, $filename, $lineno);
  });
  try {
    $result = db_select('test', 't')
      ->fields('t')
      ->condition('name', 1, $injection)
      ->execute();
    $this
      ->fail('Should not be able to attempt SQL injection via condition operator.');
  } catch (\ErrorException $e) {
    $this
      ->pass('SQL injection attempt via condition 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.');

  // Attempt SQLi via union query with no unsafe characters.
  $this
    ->enableModules([
    'user',
  ]);
  $this
    ->installEntitySchema('user');
  db_insert('test')
    ->fields([
    'name' => '123456',
  ])
    ->execute();
  $injection = "= 1 UNION ALL SELECT password FROM user WHERE uid =";
  try {
    $result = db_select('test', 't')
      ->fields('t', array(
      'name',
      'name',
    ))
      ->condition('name', 1, $injection)
      ->execute();
    $this
      ->fail('Should not be able to attempt SQL injection via operator.');
  } catch (\ErrorException $e) {
    $this
      ->pass('SQL injection attempt via condition arguments should result in a database exception.');
  }

  // Attempt SQLi via union query - uppercase tablename.
  db_insert('TEST_UPPERCASE')
    ->fields([
    'name' => 'secrets',
  ])
    ->execute();
  $injection = "IS NOT NULL) UNION ALL SELECT name FROM {TEST_UPPERCASE} -- ";
  try {
    $result = db_select('test', 't')
      ->fields('t', array(
      'name',
    ))
      ->condition('name', 1, $injection)
      ->execute();
    $this
      ->fail('Should not be able to attempt SQL injection via operator.');
  } catch (\ErrorException $e) {
    $this
      ->pass('SQL injection attempt via condition arguments should result in a database exception.');
  }
  restore_error_handler();
}