Опасность столкновения с 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;'
- класс PDO функций из PHP — вполне себе современный и значительно более надежный в работе вариант. PDO обеспечивает взаимодействие с БД со встроенным функционалом по защите от SQL инъекций. За защиту в этом случае отвечают функции prepare и execute. Первая отвечает за подготовку запроса с поправками на установленные параметры. Вторая соответственно принимает параметры из первой функции и формирует запрос к БД. У нас это будет выглядеть примерно следующим образом:
$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)'); $preparedStatement->execute(array('column' => $unsafeValue));
Подводя итоги
Второй метод из рассмотренных нами на самом деле обеспечивает не только большую степень защиты от инъекций, но и более высокую скорость обработки запросов за счет некоторых встроенных возможностей PDO . Да и банально он проще с точки зрения написания кода.