SQL-инъекция

Cтатья "Обеспечение безопасности веб-сайтов" предоставлена Sophos Plc и SophosLabs.

Декабрь 2007 г.

SQL-инъекция используется для атаки веб-сайтов, работающих с базами данных [14]. Возможность внедрения SQL-кода возникает, если в SQL-запросах используются неотфильтрованные данные, вводимые пользователями.

SQL-запросы используются для извлечения информации из базы данных, добавления информации в базу данных, а также для изменения и удаления данных в базе. Многие современные веб-сайты используют скрипты и SQL для динамического формирования содержимого страницы. В SQL-запросах часто используются данные, вводимые пользователями. Это может привести к угрозе безопасности, поскольку хакеры могут попытаться внедрить во входные данные вредоносный SQL-код. Без надлежащих мер защиты такой код может быть успешно выполнен на сервере.

Примечание.

Рассмотрим следующий PHP-код:

$firstname = $_POST["firstname"]; mysql_query("SELECT * FROM users WHERE first_name='$firstname'");

После того, как пользователь введет свое имя в веб-форме, SQL-запрос вернет список всех пользователей с тем же именем. Если указать в форме имя «Крис», то SQL-запрос будет иметь следующий вид:

"SELECT * FROM users WHERE first_name='Chris'"

Это допустимая конструкция, которая сработает так, как ожидается. Но что случится, если вместо имени ввести, например, «'; drop table; #»? Тогда конструкция будет выглядеть следующим образом:

"SELECT * FROM users WHERE first_name=''; DROP TABLE users; #'"

Точка с запятой позволяет выполнять несколько следующих друг за другом команд. В результате простая SQL-команда превращается в сложную трехсоставную конструкцию:

SELECT * FROM users WHERE first_name='';

Исходная инструкция теперь бесполезна — ее можно пропустить. Вторая инструкция приведет к тому, что в базе данных будет целиком удалена соответствующая таблица, а стоящий в третьей строке символ «#» приведет к тому, что MySQL проигнорирует оставшуюся часть строки.

Приведенная в примере уязвимость особенно опасна, поскольку ее можно использовать для вывода закрытых данных, изменения отдельных полей или удаления информации. Некоторые СУБД также позволяют выполнять системные команды с помощью SQL.

К счастью, этот вид угрозы легко устраним благодаря проверке вводимых пользователем данных. В PHP имеется специальная функция mysql_real_escape_string, удаляющая из строки потенциальный код SQL-инъекции. Ее следует использовать для фильтрации всех данных, внедряемых в SQL-инструкции.

К следующему разделу