Фильтрация запросов

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

Как это работает:

Большинство взломов сайтов происходит в результате недостаточной обработки скриптами входящих данных.
Например, если скрипт работает с БД MySQL и не экранирует в получаемых переменных из формы на сайте символ ' (одинарная кавычка) - становится возможным использование SQL-инъекции, для этого достаточно определенным образом построить содержимое переменной, передаваемой скрипту из формы на сайте.

Пример, если скрипт получает переменную $_POST['login'] использует ее в запросе к MySQL, для получения пароля, код:
//Значение переменной $_POST['login'] равно "Ivan"
//Значение переменной $_POST['password'] равно "12345"
if(isset($_POST['login']) and isset($_POST['password']){
$sql="SELECT <!--PHPSECURED-->id FROM table_users WHERE <!--PHPSECURED-->login='".$<!--PHPSECURED-->_POST['login']."' AND password='".md5($_POST['password'])."'";
}
В этом случае, скрипт отправит MySQL такой запрос:
SELECT <!--PHPSECURED-->id FROM table_users WHERE <!--PHPSECURED-->login='Ivan' AND password='827ccb0eea8a706c4c34a16891f84e7b'
Здесь "827ccb0eea8a706c4c34a16891f84e7b" - это md5-хеш числа 12345. В случае, если в таблице есть строка с переданными данными, MySQL вернет не пустой результат и скрипт отработает авторизацию.

По сути, такой скрипт должен обеспечить авторизацию пользователя Ivan, но изменим переменную $_POST['login'] вот таким образом:

<input type="text" name="login" value="Admin'; UPDATE table_users SET password<!--PHPSECURED-->='827ccb0eea8a706c4c34a16891f84e7b' WHERE <!--PHPSECURED-->login='Admin'; SELECT <!--PHPSECURED-->id FROM table_users WHERE <!--PHPSECURED-->login='Admin">
<input type="text" name="password" value="12345">
Вот теперь, скрипт отправит MySQL уже такой запрос:
SELECT <!--PHPSECURED-->id FROM table_users WHERE <!--PHPSECURED-->login='Admin'; UPDATE table_users SET password<!--PHPSECURED-->='827ccb0eea8a706c4c34a16891f84e7b' WHERE <!--PHPSECURED-->login='Admin'; SELECT <!--PHPSECURED-->id FROM table_users WHERE <!--PHPSECURED-->login='Admin' AND password='827ccb0eea8a706c4c34a16891f84e7b'
Посмотрите - фактически, скрипт отправит MySQL три запроса, причем во втором запросе он меняет пароль админа на "12345", а в третьем запросе авторизирует пользователя в качестве админа, с паролем "12345".

Это и есть SQL-инъекция.

PHPSECURE позволяет компенсировать недостаточную обработку входящих данных, защититься от SQL-инъекций, от выполнения произвольного кода и многих других угроз. Защиту такого уровня обеспечивает механизм фильтрации запросов.

Смысл очень прост - все данные передающиеся скриптам, прежде чем они будут переданы, проходят обрабоку PHPSECURE, где нежелательные данные отфильтровываются.

По умолчанию, фильтр берет нежелательное_слово и добавляет к нему тест вида <!--PHPSECURED-->, в итоге скрипту нежелательное_слово передается уже в виде нежелательное_слово<!--PHPSECURED-->.

Таким образом, если Вы просто постите на сайте (через админку CMS) какой-то текст, содержащий нежелательное_слово, то в большинстве случаев, на самом сайте отфильтрованный текст будет отображен без кода "<!--PHPSECURED-->", поскольку данный код является HTML-комментарием и не будет отображаться на странице.
Скрипт же, получит этот текст прошедшим фильтрацию, т.е. непосредственно в переменной код "<!--PHPSECURED-->" будет присутствовать.

В разделе фильтрация запросов, есть инструмент, позволяющий добавить в фильтры имена всех таблиц из указанной БД MySQL.

Таким образом, в вышеописанном примере, если бы на сайте был установлен PHPSEC, а в фильтры добавлены имена таблиц, скрипт передал бы к MySQL такой запрос:
SELECT <!--PHPSECURED-->id FROM table_users WHERE <!--PHPSECURED-->login='Admin'; UPDATE table_users SET password<!--PHPSECURED-->='827ccb0eea8a706c4c34a16891f84e7b' WHERE <!--PHPSECURED-->login='Admin'; SELECT <!--PHPSECURED-->id FROM table_users WHERE <!--PHPSECURED-->login='Admin' AND password='827ccb0eea8a706c4c34a16891f84e7b'
Обратите внимание - теперь, в той части запроса SQL-инъекции, где меняется пароль Админа и происходит авторизация в качестве Админа, имя таблицы table_users выглядит так:
table_users

А это означает, что при выполнении этих запросов возникнет ошибка, запросы не будут выполнены и пароль админа не будет изменен.

Вот так мы и защитились от SQL-инъекции из примера.

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

Теперь осталось уделить внимание непосредственно фильтрам в разделе "Фильтрация запросов", объяснить их различия и назначение.

Простые фильтры

Механизм простых фильтров довольно примитивен - PHPSEC берет указанное слово и добавляет к нему "<--PHPSECURED-->", как в примере описанном выше.
В простые фильтры имеет смысл добавить имена всех таблиц из БД MySQL, используемых на Вашем сайте - для этого в PHPSEC предусмотрен удобный инструмент.
Также, можно добавить сюда имена важных конфигурационных файлов используемых Вашей CMS, таких как config.php, wp-config.php, configuration.php и т.п.

Поскольку механизм работы простых фильтров достаточно примитивен, в редких случаях использование некоторых простых фильтров может создавать проблемы.
Например, в списке стандартных простых фильтров присутствовало слово "phpsecure" и при добавлении статей на сайте http://phpsecure.ru возникла проблема с размещением ссылок по сайту - в ссылках содержащих ключевое "phpsecure.ru", фильтр заменял его на phpsecure<--PHPSECURED-->.ru

Таким образом, стало невозможно передать ссылку на сайт http://phpsecure.ru
В подобных случаях, следует удалить проблемный фильтр.
Но что делать, если удалять фильтр не хочется, чтобы не снизить уровень безопасности, а наличие фильтра приводит к проблемам, как в вышеописанном примере?


Здесь поможет второй вид фильтров, из раздела Фильтрация запросов:

Регулярные выражения

Данный инструмент предоставляет практически безграничный контроль над передаваемыми данными и позволяет фильтровать что угодно и как угодно, не создавая не единой проблемы. Благодаря наличию регулярных выражений, только Вы решаете, что менять, чем менять и в каких случаях менять что-либо в запросах.
Единственный минус фильтров основанных на регулярных выражениях - не все знаю синтаксис регулярных выражений и умеют ими пользоваться.
На примере вышеприведенной проблемы, фильтр "phpsecure" был удален из списка простых фильтров и был добавлен в регулярные выражения, таким образом, чтобы фильтрация не препятствовала размещению ссылок на сайт http://phpsecure.ru, вот как выглядит регулярное выражение для подобного случая:
/(phpsecure[^\.][^r][^u])/us:::$1
Теперь, ссылки на сайте http://phpsecure.ru не будут отфильтрованы, но вот при попытке передать скрипту имя файла phpsecure.php или phpsecurea.php - имя отфильтруется и даже если скрипт умеет открывать файлы, имена которых передаются в переменной, конкретно эти файлы открыты им не будут.

По умолчанию, фильтр на основе регулярных выражений содержит три строчки:
/(base64_decode|gzinflate|str_rot13|chdir|getcwd|opendir|readdir|scandir|rewinddir|chmod|fopen|fread|fgets|fwrite|fputs|fgetcsv|unlink|ftruncate|flock|unpack|preg_replace|str_replace|preg_match|hexdec|fsockopen|curl_exec|fscanf|foreach|strrev|phpinfo|ini_get|ini_set|revoke|dir|file|for|while|mail|system|dl|passthru|popen|proc_close|proc_get_status|proc_nice|proc_open|allow_url_fopen|chown,chgrp|escapeshellcmd|escapeshellarg|show_source|posix_mkfifo|mysql_list_dbs|get_current_user|getmyuid|posix_setuid|posix_setsid|posix_setpgid|posix_setpgid|posix_kill|apache_child_terminate|leak|pfsockopen|mb_send_mail|exec|shell_exec|eval|set_time_limit|file_get_contents|file_put_contents)[ ]{0,}(\()/iu:::$1<!--PHPSECURED-->$2
/[^[:print:]\n\t\r\v]/uis:::
/(phpsecure[^\.][^r][^u])/us:::$1<!--PHP-SECURED-->

Вы можете изменять, удалять и добавлять регулярные выражения по своему усмотрению.

Формат:
/выражение/модификаторы:::замена
Используйте $1, $2 и т.д. переменные, чтобы вставить в замене то, что было найдено в Вашем регулярном выражении.

Поскольку регулярные выражения не являются чем-то простым даже для опытных пользователей, в разделе предусмотрен удобный инструмент для проверки Ваших фильтров.
Для того, чтобы им воспользоваться, достаточно указать что-либо в пробном запросе, нажать на кнопку (или Enter) и посмотреть, как это будет обработано.


Изредка возникают ситуации, когда скрипту требуется передать сложные данные, которые ни в коем случае нельзя как-либо менять, поскольку любое изменение в этих данных может привести к проблеме.
Примером такой ситуации может служить необходимость передать скрипту набор данных в формате CSV, с последующим добавлением этих данных в БД MySQL.
В таких ситуациях, механизм фильтрации может мешать, а сложность и многообразие передаваемых данных не позволяет написать регулярное выражение для подобных случаев.
Если ситуация возникла единоразово - можно просто временно отключить фильтрацию запросов в "Конфигурации" PHPSEC, а после отправки данных скрипту включить её обратно.
Но если такие операции выполняются регулярно, постоянно отключать-включать фильтрацию запросов станет не удобно.
Для таких случаев, в разделе Фильтрации запросов предусмотрен механизм исключений.

ИСКЛЮЧЕНИЯ

Исключения - это список файлов и директорий, для которых фильтрация запросов не выполняется.
В данный список можно добавлять папки и файлы, по одному на строку.
При этом, следует указывать абсолютный путь к файлу/папке на сервере, а не URL-адрес файла в браузере.
Папки необходимо указывать со слешем на конце, т.е. не
/home/login/dir
а именно
/home/login/dir/

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

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

Также нужно понимать, что слишком большое количество фильтров будет создавать дополнительную нагрузку - не нужно добавлять фильтры сотнями, лучше грамотно написать одно регулярное выражение.
Пусть будет меньше взломов, меньше вирусов, меньше спама! Расскажите всем!
  • Добавить ВКонтакте заметку об этой странице
  • Мой Мир
  • Одноклассники
  • Facebook
  • Twitter
  • Блог Я.ру
  • В закладки Google
  • LiveJournal
  • Яндекс.Закладки
  • MySpace
  • FriendFeed
  • Google Buzz
  • LinkedIn
  • Reddit
  • StumbleUpon
  • Technorati
  • del.icio.us
  • Digg
  • БобрДобр
  • MisterWong.RU
  • Memori.ru
  • МоёМесто.ru
  • Сто закладок
  • Блог Li.ру
  • BlinkList
  • Blogger
  • Live
  • Blogosphere News
Мы контакте - присоединяйтесь!
Скачать phpsecureinstall.tar.gz

ОДОБРЕНО

FastVPS
Хостинг WebXL
Виртуальная Выкса