Безопасность Базы Данных (SQL Injection)

Задание:  

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

 

 

Подробная инструкция:

 

  • Чаще всего инъекцию можно провести либо через GET параметры адресной строки, либо при помощи пользовательской формы. Делается это весьма несложно - если мы, к примеру, ищем какую-либо запись в базе по id из адресной строки с помощью такого запроса:

$id = $_GET['id'];

$sql = "SELECT * FROM table_name WHERE {$id}";

 

то в адресной строке можно дописать следующее: 

'page.php?id=4;DELETE FROM users;'

 

При этом всё, что было написано после знака = подставится в запрос вместо переменной $id и вся таблица с пользователями будет удалена. Это происходит потому, что разделитель ; в языке SQL - это спец символ, означающий конец запроса, после которого можно написать ещё один, при этом отработают они оба. Здесь как раз и приходят на помощь подготовленные запросы и PDO. 

 

  • Суть подготовленного выражения в том, что на место переменной мы подставляем метку (или плейсхолдер), которой затем присваивается значение нужной переменной. Метод специальной подготовки запроса  prepare() проверяет содержимое меток и автоматически экранирует все спец символы, которые после этого будут считываться как обычный текст.

 

  • Метки бывают двух видов - именованные и неименованные, но многие используют первые для повышения читабельности и наглядности кода. Выглядит это так: 

$sql = "SELECT * FROM table_name WHERE id=:id";

 

При таком способе в execute() передаётся ассоциативный массив с ключами, соответствующими названиям меток, примерно такого плана: [':id' => $id]. Есть и другой способ использования меток: 

 

$sql = "SELECT * FROM table_name WHERE id = ? AND title = ?";

 

массив для execute() в таком случае будет простым, но при этом его значения должны идти СТРОГО в том порядке, в котором расположены метки в запросе: array($id, $title)


ПОЯСНЕНИЯ И ПОЛЕЗНАЯ ИНФОРМАЦИЯ

 

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

 

  • В этом уроке мы разобрали, почему важно следить за уязвимостями своей базы данных, а так же основные аспекты, на которые стоит обратить внимание. Узнать наиболее подробную информацию про подготовленные выражения и защиту от SQL-инъекций можно в мануале PHP.net, а так же в открытом доступе сети интернет
Расскажите всем
Поделиться
Отправить