Очень неприятная уязвимость обнаружена в системе управления контентом Drupal версий от 7.0 до 7.31. Вчера вышел патч Drupal 7.32. Тем не менее, но возможность SQL-инъекции с анонимным доступом, скорее всего, приведёт к массовому взлому сайтов в ближайшие дни. На популярной CMS работает 1,1 млн сайтов, в том числе 932 тыс. используют версию 7.х. Вряд ли все успеют обновиться.
Уязвимость, найденная Стефаном Хорстом, допускает выполнение на сервере произвольных SQL-запросов от любого пользователя через интернет. Это означает, что кто угодно получает полный контроль над сайтом Drupal, может скопировать базу или запустить посторонний код. Аутентификация на сервере не требуется.
Согласно объяснению автора, проблема содержится в обработке инструкций из SQL-запроса. Так, шаблон для инструкции IN
поддерживает функцию expandArguments
для расширения массива.
protected function expandArguments(&$query, &$args) {
$modified = FALSE;
foreach (array_filter($args, 'is_array') as $key => $data) {
$new_keys = array();
foreach ($data as $i => $value) {
$new_keys[$key . '_' . $i] = $value;
}
unset($args[$key]);
$args += $new_keys;
$modified = TRUE;
}
return $modified;
}
Функция предполагает, что её вызывают для массива без ключей. Например, команда
db_query("SELECT * FROM {users} where name IN (:name)", array(':name'=>array('user1','user2')));
приведёт к выполнению такого SQL-запроса:
SELECT * from users where name IN (:name_0, :name_1)
с параметрами name_0 = user1
и name_1 = user2
.
Проблема возникает, когда мы указываем нестандартные ключи.
db_query("SELECT * FROM {users} where name IN (:name)", array(':name'=>array('test -- ' => 'user1','test' => 'user2')));
Это уже подходящий для эксплоита SQL-запрос.
SELECT * FROM users WHERE name = :name_test -- , :name_test AND status = 1
Злоумышленник получает возможность изменить, удалить базу данных, сделать дамп и т.д.