Фильтрация данных в PHP

Несколько взломов ещё на этапе роста, как веб-кодера, научили меня не доверять всем данным, приходящим от пользователя. Конечно, далеко не каждому юзеру придёт в голову писать вместо комментария XSS-код. Но всё же данные, приходящие от пользователя нужно обязательно фильтровать и проверять. Я расскажу о нескольких способов фильтрации данных с помощью PHP.
Прежде всего, следует фильтровать данные, которые передает пользователь осознанно — в основном, это данные различных форм. Это может быть пара логин/пароль для входа, пункт голосования и так далее. К примеру, имеется такая форма:
<form action="index.php" method="GET">
<input type="text" name="login">
<input type="text" name "pass">
<input type="submit" value="OK">
</form>
После нажатия кнопки "OK" передаст скрипту index.php два значения - $login и $pass. Вот пример для фильтрации переменной:
if($login)
{
$login = htmlspecialchars((stripslashes($login)), ENT_QUOTES);
$login = str_replace("/","",$login);
$login = str_replace(".","",$login);
$login = str_replace("`","",$login);
}
else
{
echo "Логин не введен!";
}
В первой строке мы проверяем существование переменной $login, если она существует — идем дальше, если нет — выводим сообщение об ошибке. Затем с помощью функции htmlspecialchars заменяем в этой переменной спецсимволы на их xhtml мнемоники.
То есть знак `<` меняется на `<`, `&` меняется на `&` и так далее. Функция stripslashes вырезает знак обратного слеша `\`. Далее с помощью str_replace вырезаем знак прямого слеша, точку (иногда бывает полезно) и обратную кавычку.
Если вы знакомы с регулярными выражениями, то предыдущий пример можно записать намного короче:
if($login)
{
if (preg_match("/[0-9a-z_]/i", $login))
{
// … действия над логином …
}
else
{
echo "Неверный логин!";
}
}
else
{
echo "Логин не введен!";
}
Этот фрагмент кода будет проверять введенный логин на соответствие регулярному выражению `/[0-9a-z_]/i`, которое означает: все цифры + все латинские буквы в любом регистре + знак подчеркивания. Если логин содержит другие символы, то будет показано сообщение об ошибке.
Аналогично фильтруются переменные, получаемые скриптом через URL. В движках сайтов можно встретить что-то вроде таких ссылок:
http://site.ru/index.php?module=news
Если не фильтровать переменную $module (или $_GET[`module`], если register_globals отключен), то над сайтом могут вытворяться не очень хорошие вещи, вроде XSS. Нужно применять первый приведенный скрипт, разумеется, убрав сообщения об ошибках.
Следующее, на чем бы я хотел остановиться — это фильтрация cookies (подробнее о создании и использовании cookies). Если вы используете SQL-базы данных, то отсутствие проверки cookiesов может привести к использованию хакерами SQL-injection. Так как в cookies, в основном, используется определенный тип данных, например, только числа, то проверку данных можно проводить с помощью все тех же регулярных выражений. Допустим, у нас есть cookies "id", в котором хранятся числовые данные. Пример его проверки:
if($_COOKIE[`id`])
{
if (preg_match("/[0-9]/", $_COOKIE[`id`])
{
// … проверяем cookies …
}
else
{
echo "Cookies не соответствует";
}
}
Приведённые мной простые примеры с реально действующих сайтов помогут Вам понять основные принципы фильтрации данных средствами PHP. Надеюсь, что Вы обратите внимание на обработку данных, поступающих от пользователя, это поможет довольно серьёзно обезопасить сайт от непрошенных гостей.
Код, 27/11/06
D3X
