Скачать справочник по MySQL

sql инъекция. Ошибки и их последствия.

В современном Интернете очень много качественно выполненных web-сайтов. Многиt из них используют довольно новую но уже хорошо развитую тенденцию хранения материала используя базы данных. Наиболее часто используются многопоточные сервера баз данных – MySQL, MSSQL а также PostgreeSQL.

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

В сегодняшней беседе мы попробуем разобраться с наиболее часто встречающимися ошибками веб приложений. Точнее говоря, попробуем разобраться что же такое SQL-injection? Самая распространенная атака хакера на базу данных — SQL Injection, при которой хакер вставляет SQL-запросы в строку URL вместо определенного параметра, и программа выполняет этот запрос. Ни в коем случае при проектировании и разработке скриптов нельзя допускать возможность использования данного вида внешнего воздействия. Литературы о защите от инъекции написано немерено, но тем не менее не профессиональные программисты все же оставляют ошибки в своих скриптах, что может печально закончится для сайта или вообще для всей фирмы(просто для примера).

Для того что бы поподробнее разобраться со всеми потенциально опасными аспектами нужно еще раз пояснить читателю как происходит построение динамичной web страницы. Итак, по запросу вида http://www.example.com/index.php?id=1 открывается скрипт index.php, но он имеет параметр id (идентификатор, наиболее часто все же программисты используют именно id). Сначала загружается шапка сайта (верхняя часть, включающая логотипы компании или же какие то рекламные показы, для нас это не принципиально в данный момент), затем из базы данных извлекается N-ая строчка, в нашем случае это 1. То. Есть из базы будет извлечена (отпарсена) первая строка из таблицы. Которая содержит в себе контент страницы (и не только, вообще, извлечется все что будет подходить под идентификатор 1). После этого вставляется нижняя часть, и готовая страница отправляется пользователю.

Логично спросить, а в чем же тогда заключается ошибка программиста если все генерируется верно? Ошибка заключается в не совсем точной фильтрации строки запроса. Если вы знаете синтаксис языка SQL то можно пропустить следующий абзац, там я расскажу о наиболее частых операторах а также мнемонических знаках.

коментарий
+ пробел
конец выражения
& и
,@ex где ex - переменная добавляет новую переменную
?ex=1 присваивает переменной ex значение 1.
set создание еще одной переменной

SELECT
– выбрать
INSERT - Позволяет добавлять данные в таблицу
UNION – Команда объединения двух запросов в один
DROP – удаление базы данных
WHERE – «где» значение

Давайте разберемся как хакер отыскивает потенциальную дырку. Предположим ваша база данных имеет таблицу USER. В которой хранится id name и password пользователя. Хакер может выполнить запрос вида :

SELECT * FROM Users WHERE id = $id

В данной SQL запросе поле id сравнивается со значением переменной $id. Если эта переменная получена как параметр сценария через URL или cookie, и не происходит никаких проверок на запрещенные символы, то запрос уязвим. Уязвимость можно обнаружить выполнив запрос вида:

SELECT * FROM Users WHERE id = 10 OR name=”admin”

Этот запрос покажет уже не только запись, в которой поле “id” равно 10, но и запись, в которой имя пользователя равно “admin”. Таким образом, хакер сможет увидеть пароль администратора и получить доступ к запрещенным данным.

Но такая ситуация поправима, необходимо всего лишь произвести фильтрацию данных в строке запроса. Реализовать это можно с помощью регулярных выражений (я предпочитаю делать фильтрацию именно через них).

<?
$id=preg_replace(”/^O-9]/”, “”, $id) ;
print(’SELECT * FROM Users WHERE id=’.$id);
?>

Как же работает данный механизм. В паттерне указано что переменная $id может принимать только числовые значения 0-9. а конструкция вида OR пате=”admin” будет ликвидирована -> данная ошибка будет исправлена, хакеру придется искать иной путь для взлома веб-приложения.

Приведенная выше защита демонстрирует простейший вариант защиты. Но в поля порой бывает нужно вводить не только цифры, а также буквы и целые слова. С этим делом все обстоит посложнее. Ну ничего, попробуем разобраться. Я исользую данную функцию, по моему мнению она является более менее верной, конечно, она не дает 100% гарантии защищенности от SQL инъекции, но тем не менее простейшие способы взлома она не пропустит. Итак, приступим к ее рассмотрению.

function prepare_param($param){
return preg_replace(”/[”a-zA-Z0-9 ]|insert|delete|update/i”,”", $param);
}
mysql_query(”SELECT * FROM Users WHERE name=”.prepare_param($name));

Паттерн задан следующим массивом разрешенных данных:

“/[”a-zA-Z0-9 ]|insert|delete|update/
Отсюда можно выделить следующие логические части.
Разрешать все буквы, верхнего и нижнего регистров, а также цифры.
| - логическое ИЛИ
SQL команды вида insert, delete и update – запрещены.

Очень распространенной ошибкой фильтрации является исключение одинарной кавычки. Чтобы усложнить взломщикам поиск ошибок в запросе, можно запретить использование сравнения ‘1’=’1’ (может быть и без кавычек, в зависимости от типа изменяемого параметра). Что это такое? Допустим, что у вас есть запрос:

SELECT * FROM name_of_table WHERE id=’$var’

Теперь представим, что $переменная доступна хакеру, и значение в ней не проверяется на служебные символы SQL. Самый простой способ увидеть содержимое всей таблицы — вставить в переменную следующее:

SELECT * FROM name_of_table WHERE id=’$var’ OR ‘1′=’1′

В секции WHERE два условия связаны оператором OR, И строки будут попадать в результат, если хотя бы одно из условий выполнено. Самое интересное — это второе условие, где написано ‘1′ = ‘1′. Оно всегда вовращает истину, а значит, в результат попадут все записи таблицы. Если запретить использование в SQL-запросе условия 1 = 1, то этот простой метод уже не сработает. Конечно же, условие можно заменить на 2 = 2, и результат будет тем же, но самое интересное, что большинство хакеров (наверное, 99 из 100) пишет именно 1 = 1.

При исследовании конкретной системы, нужно в первую очередь выяснить использует ли она SQL. Этот факт можно выявить либо косвеными путями, либо непосредственно - заставив SQL проявить себя. Если мы рабоатем с PHP, то существует только один способ определить однозначно использование SQL - это вызвать ошибку его выполнения.

Если при выполнении запроса происходит ошибка, и а PHP скрипте явно ошибки не выпонения не обрабатываются, то сообщение об ошибке PHP выдаст прямо на страницу пользователя. Как вызвать ошибку выполнения SQL запроса зависит от конкретного утройства рассматриваемой системы. В большинстве случаев ошибку можно вызвать введя в систему некорректные данные.

В заключении стоит отметить то что SQL инъекция и по сей день является очень серьезной проблемой в защите веб сайтов. Но тем не менее нужно стараться избавляться от проблем с кодом и постоянно дорабатывать его. Но SQL инъекция является не единственной серьезной опасностью которая может быть приложена к сайту. Есть еще одна вещь, называемая XSS(межсайтовый скриптинг). Но об этой тенденции и ее защите мы поговорим в следующей статье…

Оставьте свой комментарий

Внимание: Осуществляется проверка комментариев, это может отсрочить публикацию, отправлять сообщение повторно нет необходимости.