Регекс и "война" на XSS - PullRequest
       32

Регекс и "война" на XSS

1 голос
/ 09 апреля 2009

Мне всегда было интересно писать веб-программы, такие как форумы или блоги, вещи, которые требуют ограниченной разметки для переписывания в HTML. Но в последнее время я все больше и больше замечаю, что для PHP попробуйте поискать «PHP BBCode parser -PEAR» и протестировать несколько, вы либо получите неэффективный беспорядок, либо получите плохой код с дырами в XSS здесь и там.

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

// Assume input has already been encoded by htmlspecialchars with ENT_QUOTES
$text = preg_replace('#\[url\](.*?)\[/url\]#i','<a href="\1">\1</a>', $text);
$text = preg_replace('#\[url=(.*?)\](.*?)\[/url\]#i','<a href="\1">\2</a>', $text);

Работа с тегами изображений едва ли более безопасна, чем эта.

Итак, у меня есть несколько конкретных вопросов, в основном связанных с реализациями PHP.

  1. Лучше ли в этом примере совмещать только с использованием выражения проверки uri / url? Или лучше использовать (.*?) и обратный вызов, а затем выяснить, является ли ввод действительной ссылкой? Как было бы очевидно выше, javascript:alert('XSS!') будет работать в вышеупомянутых URL-тегах, но потерпит неудачу, если будет выполнено сопоставление uri.
  2. А как насчет таких функций, как urlencode() в обратном вызове, будут ли они каким-либо сдерживающим фактором или проблемой (с точки зрения стандартов URI)?
  3. Было бы безопаснее написать парсер с полным стеком? Или время и вычислительная мощность, необходимые для разработки и использования такой вещи, слишком вески для того, чтобы обрабатывать несколько разных записей на странице?

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

1 Ответ

4 голосов
/ 09 апреля 2009

протестируйте несколько, вы либо получите неэффективный беспорядок, либо получите плохой код с дырами в XSS

Да, черт возьми. Я еще не встречал реализацию bbcode, которая не была XSS-уязвимой.

'<a href="\1">\1</a>'

Ничего хорошего: не удается экранировать символы «<», «&» и «» в HTML. </p>

Лучше ли в этом примере совмещать только с использованием выражения проверки uri / url? Или лучше использовать (. *?) И обратный вызов, а затем выяснить, является ли ввод действительной ссылкой?

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

А как насчет таких функций, как urlencode () в обратном вызове

Почти; на самом деле вам нужны htmlspecialchars (). urlencode () - это кодирование параметров запроса, а здесь это не то, что вам нужно.

Было бы безопаснее написать парсер с полным стеком?

Да.

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

[url]http://www.example.com/[i][/url]foo[/i]

Может выглядеть как

<a href="http://www.example.com/&lt;i>">foo</i>

есть много других ловушек, которые генерируют неработающий код (вплоть до дыр XSS) в различных реализациях bbcode.

Я ищу принципы и лучшие практики

Если вам нужен язык, похожий на bbcode, который вы можете регулярно проверять, вам необходимо:

  • уменьшить количество возможных тегов, которые можно поместить в другие теги. Произвольное вложение на самом деле невозможно поддерживать
  • используйте специальные символы для разделителей HTML-тегов ’<’ и ‘>’, чтобы отличать их от реальных угловых скобок, которые должны отображаться как таковые в тексте. Я использую управляющие коды ASCII (предварительно отфильтровав любые управляющие символы на этапе пользовательского ввода).
  • разделяет строку, обрабатываемую этими контрольными символами, по содержанию между этими двумя контрольными символами, так что вы никогда не позволите диапазону bbcode достичь внутри тега или за границей тега.
  • потому что вы не можете, чтобы отрезки bbcode, проходящие через границы тегов, работали извне, сначала выполняя большие блочные элементы и работая внутрь со ссылками и, наконец, жирным шрифтом и курсивом.
  • для здравомыслия, обрабатывать блок за раз. например. Если вы начинаете новый

    с двойной новой строки, между двумя отдельными блоками не должно быть тегов bbcode.

Это все еще чертовски трудно получить право. Правильный синтаксический анализатор, скорее всего, будет водонепроницаемым.

...