Блог Vaden Pro

Все о самостоятельном создании и продвижении сайтов

Защита от sql инъекций

Раздел: 

Опасность столкновения с SQL атакой возникает при работе с любым сайтом использующим базы данных.

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

К внедрению вредоносного SQL кода ведет наличие возможности отправки пользователями на сайт не фильтрованных данных.

Пример SQL инъекции

$search=$_GET['query'];
$query="SELECT * FROM table WHERE field = ".$search;

В этом случае  мы можем наблюдать, что при выполнении обычного запроса SELECT мы получаем прямое обращение к базе данных сайта после получения $search из $_GET.

В чем тут угроза спросите Вы?… А представьте подобную конструкцию в передаваемом запросе:

1; DROP TABLE table;

Если еще не поняли в чем тут загвоздка, то продолжаем. При обычной настройке MySQL сервера в роли размежевателя запросов выступает «;». Делаем подстановку:

SELECT * FROM table WHERE field = 1;DROP TABLE table;

Первое действие, которое произойдет при обработке данного запроса, будет вполне себе безобидным — выбор всех полей таблицы, через запрос SELECT. Ну а дальше, если ранее не были предприняты никакие меры по настройке запросов к БД и элементарной защите БД, то все что мы выбрали мы и удалим.

Защита от SQL инъекций

Избежать возможности подобных казусов довольно просто. Достаточно просто проверять данные содержащиеся в запросах несложным обработчиком.

Работая с MySQL выбор обработчика зависит от способа передачи данных в БД. К наиболее распространенным вариантам на сегодняшний день относят следующие:

  • mysql_query — хорошо известная многим функция, которая постепенно отмирает и уже практически окончательно стала устаревшим вариантом. Если Вы по-прежнему пользуетесь ею в работе (сюда же идут mysql_connect совместно с mysql_select_db), то для создания защиты от SQL инъекции лучшим выбором будет задействовать mysql_real_escape_string. Принцип действия рассматриваемой функции достаточно прост — передаваемые переменные после обработки ею заключаются в кавычки. К чему это приводит? Запросы становятся либо не исполняемыми, либо приводят к ошибке на стороне сервера при попытке их обработать, что тоже ни к чему опасному для нас не ведет. Если применить этот метод защиты к нашему примеру, то получим примерно следующий код:
    $search=$_GET['query'];
    $search=mysql_real_escape_string($search);
    $query="SELECT * FROM table WHERE field = ".$search;
    В итоге все сработает как и положено и полученный запрос:
    SELECT * FROM table WHERE field = '1;DROP TABLE table;'
    Будет вполне безопасен. По таблице пройдет поиск данный с содержанием '1;DROP TABLE table;', дальнейшего удаления данных не последует.
  • класс PDO функций из PHP — вполне себе современный и значительно более надежный в работе вариант. PDO обеспечивает взаимодействие с БД со встроенным функционалом по защите от SQL инъекций. За защиту в этом случае отвечают функции  prepare и execute. Первая отвечает за подготовку запроса с поправками на установленные параметры. Вторая соответственно принимает параметры из первой функции и формирует запрос к БД. У нас это будет выглядеть примерно следующим образом:
    $preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');
     
    $preparedStatement->execute(array('column' => $unsafeValue));
    По сути все достаточно очевидно, пройдемся по происходящему подробнее: $preparedStatement в первой стоке это еще не запрос к БД, а только объект PHP. Создавая его функцией prepare мы разрешаем участвовать в запросе единственному параметру :column. При желании мы можем указать столько параметров, сколько нам будет угодно. Согласно синтаксису начинатьcя они должны с «:». На следующем шаге происходит запрос и передача массива с параметрами в функцию execute. Защита от инъекций происходит автоматически при передаче запроса.

    Подводя итоги

    Второй метод из рассмотренных нами на самом деле обеспечивает не только большую степень защиты от инъекций, но и более высокую скорость обработки запросов за счет некоторых встроенных возможностей PDO . Да и банально он проще с точки зрения написания кода.