PHP Дыры в большинстве preg_match фильтров

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

Большинство PHP-разработчиков используют символы ^ и $ в своих регулярных выражениях, до конца не понимая что они получают в итоге. Можно встретить очень много фильтров наподобие такого:

<?php
   $clean = array();
   if (preg_match("/^[0-9]+:[X-Z]+$/", $_GET['var'])) {
      $clean['var'] = $_GET['var'];
   }
?>

Довольно распространенный способ фильтрации входных данных, не так ли?

Однако, проблема в том, что автор такого регулярного выражения читал документацию не совем внимательно и ошибочно полагает, что символ доллара ($) однозначно определяет конец строки. На самом деле это не совсем так. Даже в документации по PHP сказано, что символ $ означает конец строки или "почти конец", имея ввиду что за ним еще может следовать один единственный символ переноса строки (\n). А это означает, что следующий запрос успешно пройдет через этот фильтр:

http://server.tld/index.php?var=012345:XYZ%0a

В некоторых случаях символ переноса строки может быть опасным. Например, когда вы хотите предотвратить разделение ответов HTTP или Email-инъекции. Чтобы это исправить, необходимо добавить в регулярное выражение модификатор D. Этот модификатор указывает, что символ $ действительно является концом текста и ничем более. Вот правильный код:

<?php
   $clean = array();
   if (preg_match("/^[0-9]+:[X-Z]+$/D", $_GET['var'])) {
      $clean['var'] = $_GET['var'];
   }
?>

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

  30 декабря 2008  |    PHP  |    Spider
  php, безопасность

Комментарии (9)

Adenim | 31 декабря 2008, 21:23
Спасибо, получил полезную информацию, учту в своей будущей работе.
Porter | 16 февраля 2009, 17:08
Рельно,  проверил, действительно так и есть.
Спасибо за совет.
Holy Diver | 10 апреля 2009, 11:10
Да, полезная мелочь этот /D. Раньше внимания не обращал, но скрипты переписывать не брошусь - ибо слишком узкая уязвимость и очень мало мест для её использования в реальных проектах.
Виталий | 20 сентября 2009, 12:58
Стаття супер!Надеюсь на продвижения етого блога!
Dmitry Evteev | 22 февраля 2010, 15:10
кто бы мог подумать... реально, круто!
Максим Нагайченко | 26 марта 2010, 15:25
Спасибо за то, что читаешь доки от и до))) Я вижу ты Коханой интересуешься, подпишусь на тебя.
fvfv | 6 января 2011, 21:06
Спасибо большое!
AleX | 14 июня 2011, 14:16
Спасибо
Михаил | 19 июня 2011, 00:16
Таки да. как раз только что воевал с регистрацией в Prestashop - там именно так и написана вся валидация данных и в итоге вылазили ошибки но некоторым полям. Без $ - всё работает. Приятно, что сам додумался, а потом наткнулся на статью Well

Добавить комментарий

Ваше имя: *
Ваш e-mail: * (не публикуется)
Адрес сайта:
Комментарий: *
полужирный курсив курсив курсив вставить ссылку

  

Новости сайта в RSS

Категории

Статьи

Новые Популярные Комментируемые

Облако меток

Разное

Продажа авто Воронеж, покупка авто в Воронеже, авто с пробегом в Воронеже