Безопасное программирование в PHP: SQL-инъекции

Февраль 1, 2008

SQL-инъекция является очень распространенным типом атак на ресурсы. Неправильное проектирование системы и отсутствие фильтрации входных данных может привести к тому, что ваша база данных может быть получена/испорчена злоумышленником.

Характерным признаком для SQL-инъекций является наличие SQL-запросов или его составляющих в передаваемых параметрах. Рассмотрим простейший случай.

Адрес вашей страницы выглядит так: http://www.hacked-resource.com/page.php?cat_id=1
Получение id-страницы выглядит вот так:

<?php
$cat_id=$_REQUEST['cat_id'];
?>

Ваша страница выводится запросом

<?php
//// .... ////
mysql_query('SELECT * FROM content WHERE cat_id='.$cat_id);
////....///
?>

При отсутствии фильтрации и попытке запросить страницу с адресом http://www.hacked-resource.com/page.php?cat_id=1+or+1=1 ваш скрипт выведет все записи из таблицы content.

В адресе атакуемой страницы мы наблюдаем кусок SQL-инструкции «+or+1=1». Собрав и проанализировав такие «бутылочные горлышки» вашей системы вы прийдете к выводу, что необходимо обеспечивать должный уровень фильтрации данных. Никто не спорит, что это непросто... Однако, элементарный список SQL-инструкций и его соспоставление на вхождение в URI весьма уменьшит риск подобных «хулиганств».

Конечно же, это поможет только при элементарных знаниях взломщика. Чтобы написать систему, которая будет способна противостоять хакеру, вам необходимо иметь хотя бы тот же уровень знаний, что и у него.

Очень немногие «программисты» знают о возможности полного html-кодирования строк, не говоря уж о SQL-комментариях. Если элементарные меры и могут противостоять попыткам взлома, но они в 99% неэффективны при усложнении запросов, хотя бы до уровня
http://www.hacked-resource.com/page.php?cat_id=/*абракадабра*/1+or/*абракадабра*/+/*абракадабра*/1=1

4 комментариев на “Безопасное программирование в PHP: SQL-инъекции”

  1. sitetime высказал:

    А в каких именно случаях не хватает mysql_real_escape_string ()?

  2. Jeurey высказал:

    Использование подобных функций может нивелироваться различными настройками сервера. Например, если сервер не экранирует сам входящие параметры — можно попытаться привести входящую строку к виду SQL-комментария (если будет использована mysql_escape_string или mysql_real_escape_string). Не факт, что получится — ведь все зависит от параметров компиляции...

    Как показывает практика, самостоятельная компиляция — это уже полдела, но не у всех есть возможность пересобрать ПО на хосте, да и понимать нужно, что делаешь :)

  3. Anarki высказал:

    «Однако, элементарный список SQL-инструкций и его соспоставление на вхождение в URI весьма уменьшит риск подобных “хулиганств”.»

    Проще будет в SQL запросах провести «закавычивание». Параметры в SQL передавать в кавычках, например.

    SELECT * FROM table WHERE id='param';

    Где param — пропущенный через mysql_real_escape_string параметр.

    Злоумышленник не сможет толком ничего сделать.

  4. jeurey высказал:

    «Злоумышленник не сможет толком ничего сделать.»

    Здесь слово «толком» случайно? )