2009-04-09 3 views
1

Я всегда интересовался написанием веб-программного обеспечения, такого как форумы или блоги, которые имеют ограниченную разметку для переписывания в HTML. Но в последнее время я все больше и больше заметил, что для PHP, попробуйте googling «PHP BBCode parser -PEAR» и протестируйте несколько, вы либо получаете неэффективный беспорядок, либо получаете плохой код с отверстиями XSS здесь и там.Regex и «war» на 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-защиты в ситуации синтаксического анализа.

ответ

4

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

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

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

Ничего хорошего:. Не в HTML-бежать '<', '&' и '"' символы

Это лучше практика, в этом примере, чтобы соответствовать только с использованием URI/выражение проверки URL? или, лучше использовать (. *?) и обратный вызов, а затем выяснить, является ли вход действительной ссылка?

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

насчет функций, таких как 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-подобный язык, который вы можете Regex, вам нужно:

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

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

+0

Хм, я согласен с вами в том, что вы сказали, но у меня не было большого мастерства в создании правильного парсера. Знаете ли вы о приличных учебниках для анализа XML-esque? Мне было трудно найти хорошую, которая не слишком сложна, но все же на уровне навыков, необходимых. –

+0

Если вы не можете найти стороннюю парсерную библиотеку, которая удовлетворяет ваши потребности, вы можете сделать это вручную: сначала preg_split-with-PREG_SPLIT_DELIM_CAPTURE над строкой с чем-то вроде «\ [[^ \]] + \] ' выберите теги, затем перейдите в список, содержащий стек открытых тегов. – bobince

+0

(Индексы с нулевым номером в списке будут тегами с тегами с нечетным номером. Обычно текст будет выведен из HTML-кода, и, возможно, если вы это сделаете, смайлики будут автозаполнены, но некоторые теги могут изменить это.) – bobince

 Смежные вопросы

  • Нет связанных вопросов^_^