Многие мне пишут, что бы я что нить доделал в чужих разработках. И мне приходится иногда исправлять ошибки самих разработчиков. Я сам когда то делал подобные ошибки, но теперь стараюсь все входящие данные пропускать через фильтр.
Много кто для фильтров использует регулярные выражения (preg_match) и допускают много ошибок. Ошибка заключается в символах ^ и $. Разработчики - новички когда пишут эти выражения не до конца понимают что они получают в итоге. Например, возьмем вот такой пример:
<?php
$zv = array();
if (preg_match("/^[0-9]+:[X-Z]+$/", $_GET['vit'])) {
$zv['vit'] = $_GET['vit'];
}
?>
Довольно распространенный способ фильтрации входных данных, не так ли?
Однако, проблема в том, что автор такого регулярного выражения читал документацию не совcем внимательно и полагает, что символ доллара ($) однозначно определяет конец строки. На самом деле это не совсем так! Даже в документации по PHP сказано, что символ $ означает конец строки или почти конец, имея ввиду что за ним еще может следовать один единственный символ переноса строки (\n). А это означает, что следующий запрос успешно пройдет через этот фильтр:
http://zvlad.lan/index.php?vit=236154:VLAD%0a
В некоторых случаях символ переноса строки может быть опасным. Например, когда вы хотите предотвратить разделение ответов HTTP или Email - инъекции. Чтобы это исправить, необходимо добавить в регулярное выражение модификатор D. Этот модификатор указывает, что символ $ действительно является концом текста и ничем более.
Вот правильный код:
<?php
$zv = array();
if (preg_match("/^[0-9]+:[X-Z]+$/D", $_GET['vit'])) {
$zv['vit'] = $_GET['vit'];
}
?>
Я надеюсь, что эта статья помогла вам и отныне вы будете писать только правильные фильтры с использованием регулярных выражений.
P.S.: Этот способ фильтрации я наиболее не люблю :)
- Владислав
- 24-02-2012, 12:05
- 5 038