Абстрактный доступ к базам данных,
такой как php Portable Data Objects (PDO)
вовсе не какая-либо новая концепция в
программировании, но многие из
разработчиков до сих пор не осознают в
полной мере какие преимущества в
области защиты кода предоставляет
использование данной технологии, в
данной статье речь пойдет о SQL
инъекциях.
SQL инъекция – это код или запрос к БД,
направленный на переполнение буфера
web-приложения. Каждый разработчик
скриптов должен заботиться о том, чтобы
разрабатываемый им код был защищен
от подобных уязвимостей. Для тех кто не
в курсе, SQL инъекция – это техника
применяемая хакерами, использования
«дыр» программного кода для выполнения
произвольных SQL запросов, приводящих
к уничтожению, повреждению или
непредусмотренной модификации данных.
В данной статье мы не будем глубоко
вникать в философию SQL инъекций, но
небольшой пример, думаю, привести стоит:
Главная страница вашего сайта содержит
форму входа пользователей, связанную с
php скриптом, который определяет статус
пользователя (зарегистрированный или
нет) и наделяет его определенными
полномочиями или делает доступным
определенный дополнительный набор
сервисов сайта. Форма входа передает
сценарию две переменные методом POST:
username = fred &password =Fr3dRul3z
Пученные данные используются при
построении SQL запроса к БД, для
идентификации пользователя:
$sql = \"SELECT * FROM users WHERE username = \'\" .$_REQUEST [ \'username\' ] . \"\' AND password = \'\" . $_REQUEST [ \'password\' ] .\"\'\" ;
Данный код сформирует запрос:
SELECT * FROM users WHERE username = \'fred\' AND password = \'Fr3dRul3z\'
Допустим, в базе присутствует строка с
такими данными – пользователю будет
разрешен вход на сайт. Опытный хакер
сможет легко обойти данную систему
контроля, путем исключения из SQL
данных логина пользователя. При этом в
поле логина будет введено:
\' OR 1==1 --
А поле пароля нужно оставить пустым. В
итоге SQL запрос к базе данных примет
вид:
SELECT * FROM users WHERE username = \'fred\' OR 1== 1 -- \' AND password = \'\'
В результате такого запроса в БД будут
выбраны все пользователи, так как
выражение 1==1 всегда истинно. Вторя
часть запроса блокируется оператором
комментария ‘--‘. Чтобы избежать атаки
подобного рода, необходимо проверять
данный полученный из формы и удалять
все, что может быть использовано для
модификации SQL запроса. В случае
работы с MySQL вы можете
воспользоваться функцией
mysql_real_escape_string().
Основная цель слоев абстрагирования баз
данных подобно PDO - чистая абстракция
кода не связанная с базой данных, таким
образом, теоретически появляется
возможность переключения между базами
MySQL, PostgreSQL или Oracle с
минимальными модификациями
программы. На практике все зависит от
того на сколько ваш код привязан к
определенной платформе, например к
триггерам или хранимым процедурам, но
если вы не зависите от них вообще, т.е.
просто работаете с обычными запросами
типа INSERT/UPDATE/DELETE – у вас не
должно возникнуть никаких сложностей.
Еще одно полезное свойство –
предопределенные выражения,
большинство слоев абстракции баз
данных (включая PDO) реализуют этот
механизм как возможность выполнения
одинаковых запросов много раз, но с
разными параметрами. Теперь, мы
построим запрос по методологии PDO. За
основу возьмем SQL запрос приведенный
выше. Выражение разработаем с
использованием меток-заполнителей:
$sql = \"INSERT INTO fruits (name, price) VALUES (?, ?)\" ;
и выполним запрос со следующими
предустановленными параметрами,
переданными в слой абстракции
следующим образом:
$sth = $dbh -> prepare ( $sql) ;
$sth -> execute (array ($fruit , $price )) ;
Когда данные обработаны в PDO, они
напрямую передаются драйверу базы
данных, либо запрос строиться
безопасным образом внутри данного
расширения. Как можно заметить, это
простой путь решения проблемы с SQL
инъекциями.
Однако при использовании
предопределенных выражений совместно с
PDO необходимо знать некоторые нюансы,
чтобы избежать неприятных ситуаций.
Например, в MySQL клиенте некоторые
запросы, составленные посредством
предопределенных выражений, не могут
быть выполнены[1], а так же они не
используют кэш [1][2], что может
замедлить работу вашего web-
приложения.
Гарантированная безопасность при
использовании предопределенных
выражений звучит успокаивающе, но
разработчики не должны принимать PDO и
другие слои абстракции
\\предопределенные выражения за
абсолютную защиту от взлома. Любые
входящие данные должны проверяться,
PDO – дополнительная линия обороны.
Это расширение не закрывает все
множество уязвимостей, посредством
которых может быть нанесен вред вашей
информации, но в то же время, PDO
неплохо справляется с вопросом
предотвращения SQL инъекций.
PDO является частью php начиная с
версии 5.1.0, вышедшей в ноябре 2005.
Откдуа скопировал?