Защита от SQL инъекций в PHP. Фильтрация переменных Обучающий материал

Очень часто при работе с кодом других PHP разработчиков натыкаюсь на множество участков кода, где происходит обращение для какой либо процедуры к БД и это обращение НИКАК не защищено от SQL инъекций.

Для примера. Полный текст страницы сайта выводиться из БД по её ID, т.е. пользователь видит ссылку на эту страницу такого вида:

https://site.ru/?page=23

В коде PHP это выглядит так:

if($_GET['page']) {
	$page = mysql_fetch_array(mysql_query("SELECT * FROM pages WHERE id = ".$_GET['page']));
   	 echo $page['content'];
}

Тут видна явная уязвимость из-за отсутствия фильтрации переменных в sql — запросе, так как что помешает злоумышленнику ввести в адресную строку

https://site.ru/?page=23'+UNION+SELECT

В итоге в БД уйдет запрос несколько другой чем мы ожидали.

Главное правило – не доверяйте пользователям при разработке чего либо.

Способы защиты от SQL инъекций


1) Если мы точно знаем что в переменной должно быть число, как в примере выше, следует использовать функцию intval() для преобразования всего содержимого переменной в число

$page = "23'+UNION+SELECT"; //попытка внедрения
$page = intval($page);
echo $page; //Выведет нам просто число 23

Больше нет необходимости как то фильтровать эту переменную. От её значения останется только цифра.

2) Защита от SQL инъекций через фильтрацию строковых переменных. Для фильтрации строковых переменных используются следующие функции фильтрации переменных в sql

$name = addslashes($_POST[name]); //Экранирует спец. символы в строке //не рекомендуется, так как функция не учитывает кодировку вашей БД
$name = mysql_real_escape_string ($_POST[name]); //Также как и предыдущая функция экранирует спец. символы. Рекомендуем для защиты от sql инъекций. 
//Пример
$page = "23'+UNION+SELECT"; //попытка внедрения
$page = mysql_real_escape_string ($page);
echo $page; 
//Выведет нам «23\'+UNION+SELECT»

Также если Вы НЕ хотите чтобы в переменной присутствовали теги HTML кода, рекомендуем провести следующую фильтрацию в sql запросе

$page = "23'+UNION+SELECT +<br />"; //попытка внедрения
$page = mysql_real_escape_string(htmlspecialchars(strip_tags(strval($page))));
// strip_tags() – вырезает HTML теги
// htmlspecialchars() – превращает спец. символы в html сущности, например '<' превратиться в '& lt;'
echo $page;
// Выведет нам         23\'+UNION+SELECT +

Для дополнительной защиты от sql инъекций можете использовать ниже представленную нами простенькую функцию, она проверит присутствие SQL команд (union, char, select, update, group, order, benchmark) в переменной и, если найдет, то скрипт сразу прекратит свою работу

$deny_words = array("union","char","select","update","group","order","benchmark");
	
str_replace($deny_words, "", strtolower($text), $count); // (что ищем, если найдем - на что заменим, где ищем(фильтруемая переменная), сколько раз нашли и заменили)
	
if ($count > 0) {
    exit('SQL - inj'); // Если было найдено хоть одно "запретное" слово, что произойдет остановка скрипта с текстом ошибки
}

38 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.