Блог студии веб-дизайна «Make a Site» Дизайн, верстка, программирование, наполнение и раскрутка сайтов.

Защита сайта от SQL инъекций

SQL инъекция (SQL injection) — внедрение постороннего SQL запроса в основной запрос к базе данных методом добавления его к GET или POST данным с целью взлома сайта.

Защита сайта от SQL инъекций

Большинство сайтов, размещенных на данный момент в интернете, для хранения информации используют базы данных, а т. к. язык программирования PHP является одним из самых популярных и наиболее часто используемым для создания веб-сайтов, то речь пойдет о стандартной связке — PHP + mySQL.

SQL — язык структурированных запросов (structured query language) используется в связке с самым популярным на данный момент языком программирования PHP, наиболее подходящим для создания обычных веб-сайтов. В подавляющем большинстве случаев для хранения данных на сайте необходима база данных mySQL. Исключение составляют единичные случаи — одностраничные сайты на самом дешевом хостинге без поддержки PHP и mySQL за ненадобностью. Нет смысла устанавливать систему администрирования и подключать базу данных для сайта, информация на котором меняется раз в квартал, а то и реже или вообще не меняется никогда. Да и платить втридорога за это тоже смысла никакого нет. Однако речь идет о большинстве сайтов, которые все-таки используют системы администрирования, а следовательно подключены к базе данных.

То, какой запрос посылается базе данных, часто зависит от переменных параметров, передающихся методом GET или POST. Как известно, GET — незашифрованные данные, передающиеся путем добавления атрибутов к адресу страницы, а POST — зашифрованные данные, которые передаются посредством форм. В обоих этих случаях существует уязвимость на предмет SQL инъекций. Давайте рассмотрим, как можно сделать простую SQL инъекцию на конкретном примере.

Представьте себе, что на каком-то сайте есть новости. Новости хранятся в базе данных в таблице с названием news. Для того, чтобы человек в браузере мог открыть ту или и иную новость, необходимо менять URL в зависимости от того, какую именно новость нужно достать из базы данных. Т. е. news?id=1 означает, что нужна первая новость, news?id=2 — вторая и так далее.

http://makeasite.ru/?p=571 — короткая ссылка на данную страницу, которая не преобразуется в формате ЧПУ (человеко понятный урл). Как видно из ссылки, параметр p (post) принимает значение 571, а значит в базу данных передается примерно такой запрос (в условном виде и специально незащищенный для примера):

/* URL — http://makeasite.ru/?p=571 */
$rs = mysql_query("SELECT * FROM `posts` WHERE `ID` = ".$_GET['p']);
/* Результат: SELECT * FROM `posts` WHERE `ID` = 571 */

В базе данных в таблице posts находится строка с идентификатором, равным 571 и данные выводятся на экран. А теперь давайте на данном примере рассмотрим, как можно сделать самую простую SQL инъекцию, изменив URL под свои нужды.

/* URL — http://makeasite.ru/?p=571;+TRUNCATE+TABLE+`posts` */
$rs = mysql_query("SELECT * FROM `posts` WHERE `ID` = ".$_GET['p']);
/* Результат: SELECT * FROM `posts` WHERE `ID` = 571; TRUNCATE TABLE `posts` */

Как видите, путем простого изменения GET-запроса нами была проведена SQL инъекция, благодаря которой теоретически можно полностью очистить выбранную нами таблицу. Если немного подробней, то мы завершили первый запрос при помощи точки с запятой, а затем написали свой собственный запрос, который должен выполниться следом и заменили пробелы на знаки "+" (это необходимо для передачи строки методом GET, т.к. пробелы в адресной строке недопустимы). Если бы мы делали это методом POST, через форму, нам не нужно было бы добавлять знаки "+".

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

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

/* URL — http://makeasite.ru/?p=571;+TRUNCATE+TABLE+`posts` */
if(intval($_GET['p']) > 0) {
	$rs = mysql_query("SELECT * FROM `posts` WHERE `ID` = '".intval($_GET['p'])."' LIMIT 1");
}
/* Результат: Никакого запроса не будет */

Целое число может быть и отрицательным, а нам нужны только положительные значения, поэтому, добавив простую проверку, мы исключим вероятность несанкционированного проникновения. Также можно использовать функцию is_numeric(), по большей части все зависит от того, какие данные ожидается получить для дальнейшего использования в SQL запросе к БД.

Часто бывает так, что на сайте есть форма поиска, в которую пользователи могут вводить произвольные тексты, после чего происходит обращение к базе данных с использованием полученных извне параметров. В таком случае нужно "обрамлять" POST данные в запросе одинарными кавычками и добавлять функцию экранирования спецсимволов mysql_real_escape_string(), которая вообще не оставляет пространства для действий злоумышленников, пытающихся сделать SQL инъекцию.

В случае, если вы сомневаетесь в том, что ваш сайт защищен от SQL инъекций должным образом, нужно как можно скорее постараться закрыть всевозможные бреши в обороне, а также взять за правило не лениться и регулярно производить резервное копирование как файловой системы сайта, так и используемой им базы данных. Кроме всего прочего, если на вашем сайте существует возможность регистрации и вы храните данные пользователей в незащищенном виде, нужно позаботиться о том, чтобы хранение паролей зарегистрированных пользователей сайта осуществлялось в защищенном, а не в явном виде. Для этого обычно используются функции для преобразования строки в хеш — MD5, SHA-1 и так далее.

Обычно защита от SQL инъекций изначально заложена во все популярные системы управления, но не забывайте о том, что устанавливая множество плагинов сторонних разработчиков вы подвергаете свой сайт опасности несанкционированного доступа к файлам или базе данных. Причем, чем больше установлено плагинов, тем больше вероятность, что какой-то дотошные хакер все-таки найдет дырку в обороне и осуществит свой злой замысел. Старайтесь устанавливать только самые необходимые плагины, а не все подряд и используйте только самые популярные из них. То же самое касается и выбора CMS, чем популярней, тем больше было разнообразных попыток взлома и введения SQL инъекций в частности, а значит, тем лучше она защищена разработчиками, наученными горьким опытом.


Предыдущая статья:
Хранение паролей пользователей в форматах MD5 и SHA-1

Читайте также:
CSS градиент фона двумя способами — линейный градиент и внутренняя тень


Блог студии веб-дизайна «Make a Site».
Дизайн, верстка, программирование, наполнение и раскрутка сайтов.

Текущий проект: «Stream Booster» — раскрутка Twitch и YouTube каналов

Студия веб-дизайна «Make a site»