Начну с того что сегодня мы поговорим о том как защитить свой проект от SQL инъекций тема эта давно наболевшая и думаю, будет интересна многим! SQL инъекции как вам известно надеюсь уже всем очень распространены и похожи на XSS-атаки подробнее о них в статье "Как защититься от XSS атаки и устранить уязвимость", основаны они на внедрении произвольного SQL-кода в какой-либо запрос и в результате злоумышленник получает из базы данных необходимую ему секретную информацию или просто удаляет всё. Что бы этого не произошло, мы и будет от них спасаться!
Для начала я на примере запроса формы авторизации на сайте покажу, как работают инъекции.
Пользователь вводит логин и пароль, а далее идёт сравнение введённых данных с теми, что есть в базе данных.
SELECT * FROM users WHERE login = "$_POST['login']" AND passw = "$_POST['passw']"
Если нет проверки данных то можно делать всё что угодно. К примеру вместо логина можно ввести admin"/*, а в качестве пароля что угодно или не вводить ничего тогда запрос будет выглядеть так:
SELECT * FROM users WHERE login = "admin"/* AND passw = ""
Такой запрос у нас пройдет как валидный, и пользователь сможет зайти под логином admin. Это скажет нам о том, что нужно проверять вводимые данные! А проверять лучше всего на уровне PHP, а так же желательно и Jvascript это будет надёжнее, дело в том что если к примеру у вас на сервере включён register_globals по проверка на уровне PHP будет бесполезна подробнее в статье
Почему опасно включать параметр register_globals.
Перейдём теперь к защите от SQL инъекции, заключаться она будет в том что бы выкинуть все вводимые не числовые символы , сделать это можно двумя способами :
Первый способ.
Проверяем числовые строки , показывая сценарию, что передаваемое значение именно число.
$number = (int)$_POST['number'];
Второй способ.
Замена по регулярному выражению, где обрубается всё кроме цифр. И если передаётся не число, то в переменную $number попадёт нолик.
$number = preg_replace ("/[^0-9]/", "", $_POST['number']);
Страшного тут ничего нет, но только в случае, если есть какая-то секретная нулевая запись. Впрочем сценарий всегда можно переписать проверив является ли значение нулём.
С текстовыми строками всё обстоит серьёзней, к примеру, если нужны только буквы и цифры, то все остальные символы может спокойно отрубить Regexp:
$string = preg_replace ("/[^a-zA-Z0-9]/i", "", $_POST['string']);
Но бывают такие случаи, когда нам нужно использовать скобки или галочки. Для этого мы должны разобраться, какие символы вообще нельзя использовать (напрямую) и нужно заменить специальными.
К примеру, одинарные и двойные кавычки используются в запросах для выделения, проверить их нам поможет
htmlspecialchars, а так же
addslashes.
Что касается знака равенства, то он тоже может быть нам опасен, если его не вено применить. К примеру, имеем запрос:
$sql = 'SELECT * FROM users WHERE id='.$id;
Передаём в качестве параметра 1 OR name="admin". В результате запрос будет выглядеть как:
SELECT * FROM users WHERE id=1 OR name="admin"
Думаю всем понятно, что если запретить символ равенства, то вместо name="admin" будет name"admin", а это приведёт к ошибке и запрос не прокатит.
Что касается символов комментария (двойных тире, слешей со звездочкой) всё почти как с комментированием в PHP, вместо двойного слеша используется двойное тире и комментирует только одну строку, а слеш со звёздочкой точно также обозначен, только в SQL комментирует до конца запроса и его можно не закрывать.
Для примера есть запрос:
SELECT * FROM users WHERE name=$id AND password=$pass
Если мы внедрим вместо $id значение 1-- то последняя строчка с паролем не закомментируется и инъекция не пройдёт. Но всё будет иначе, если вместо двойного тире использовать /*, тогда последняя строчка закомментируется.
Кроме того что используя эти уязвимости можно вытянуть или удалить информацию с базы данных можно ещё и слить всю информацию с базы в файл или произвести дефейс сайта.
Пример:
SELECT * INTO OUTFILE 'file.php'
Так можно создать собственный сценарий на сайте и уже плясать от него. Да и если файлы сценариев доступны для записи всем, то можно произвести дефейс:
SELECT '<b>YOU HACKED!</b>' INTO OUTFILE 'index.php'
Вот и всё вроде рассказал вам основные моменты если что-то не понятно обсуждайте, спрашивайте, будем разбираться и дополнять сайт полезной информацией! Удачи берегите свои сайты!
Отзывы