Comments 20
Для данной задачи лучше не использовать чёрный список, т.к. слишком высока вероятность того, что что-то будет упущенно, а также потребуется переодически дополнять его.
Также, иногда для атак используются незакрытые теги или теги с незакрытыми аттрибутами, которые исправляет уже браузер. Скорее всего, решение с loadHTML не сможет обработать такие ситуации.
Также, иногда для атак используются незакрытые теги или теги с незакрытыми аттрибутами, которые исправляет уже браузер. Скорее всего, решение с loadHTML не сможет обработать такие ситуации.
Тут скорее вопрос полезности комбинации множества решений, когда есть тот же HTML Purifier и аналоги.
Статья описывает интересный подход к решению проблемы, который будет сложно применить на практике.
Статья описывает интересный подход к решению проблемы, который будет сложно применить на практике.
С моей точки зрения полезность предлагаемого решения в его универсальности — XSLT это универсальное средство, которое может быть применено на почти любом языке программирования, в почти любом фреймворке и не требует для понимания дополнительных знаний кроме знания XSLT.
Можно сказать что по сравнению с HTML Purifier и аналогами это то же самое что и XSLT-шаблоны по сравнению со Smarty и аналогами.
Можно сказать что по сравнению с HTML Purifier и аналогами это то же самое что и XSLT-шаблоны по сравнению со Smarty и аналогами.
Белые списки не могут описать все нюансы, например использование зловредного кода внутри разрешённого href. А раз так, и всё равно придётся использовать чёрные списки, то можно обойтись только ими, либо использовать и то, и другое.
Если вам на вход придет html-документ, не являющийся валидным xml, xslt шаблон не сможет его преобразовать, и это большая проблема.
Наиболее частые проблемы, из-за которых html документ может оказаться невалидным xml (но при этом валидным html)
Любая из этих проблем порушит ваш xslt-фильтр, при этом в принципе все они достаточно часто встречаются в коде, который генерируется визивиг-редакторами.
Наиболее частые проблемы, из-за которых html документ может оказаться невалидным xml (но при этом валидным html)
- незакрытые теги переноса строки (
<br>
вместо<br />
) - незакрытые изображения, input и т.д. (
<img src="">
вместо<img src="" />
) - аттрибуты без значений (
<option selected />
вместо<option selected="selected" />
) - неопределенные сущности (
вместо 
) - символ
<
, который не открывает тег (например<script> if(a < b)</script>
вместо<script> if(a < b)</script>
)
Любая из этих проблем порушит ваш xslt-фильтр, при этом в принципе все они достаточно часто встречаются в коде, который генерируется визивиг-редакторами.
Привести невалидный документ к валидному не очень сложно, и после этого уже проходится xslt — Вам же в любом случае нужен валидный HTML на страничке, так?
Я это делаю с помощью SAX парсера (а можно делать и кучей других уже готовых вариантов). принцип простой:
Вобщем както так )
Я это делаю с помощью SAX парсера (а можно делать и кучей других уже готовых вариантов). принцип простой:
- получили открывающй элемент, положили в стэк
- встретили открывающий элемент, который не должен пресекаться с верхнем элементом стэка — закрыли его, убрали со стэка, положили в стэк новый
- иначе просто положили в стэк новый
- при встрече закрывающего элемента, не совпадающего с верхнем элементом стэка — пропустили его
- иначе убрали со стэка
Вобщем както так )
Описанный принцип реализует только закрытие незакрытых элементов (2 проблемы из 5).
Понятно, что привести HTML документ к xHTML в автоматическом режиме вполне возможно (есть даже уже написанные конвертеры, например на JS), вопрос в том, насколько оправдано поддерживать целый html -> xhtml конвертер ради такой простой задачи как фильтрация «опасных» тегов и аттрибутов в пользовательском вводе.
На мой взгляд, для большинства прикладных задач — неоправданно.
Так я поэтому в первом комментарии и заметил что ни одна из обохзначенных мной проблем не делает html невалидным.
Понятно, что привести HTML документ к xHTML в автоматическом режиме вполне возможно (есть даже уже написанные конвертеры, например на JS), вопрос в том, насколько оправдано поддерживать целый html -> xhtml конвертер ради такой простой задачи как фильтрация «опасных» тегов и аттрибутов в пользовательском вводе.
На мой взгляд, для большинства прикладных задач — неоправданно.
Вам же в любом случае нужен валидный HTML на страничке, так?
Так я поэтому в первом комментарии и заметил что ни одна из обохзначенных мной проблем не делает html невалидным.
Я считаю что приводить пользовательский ввод к XHTML вполне оправданно. Это позволяет как минимум отдавать полностью корректный HTML в браузеры. Я знаю что стандарт HTML не требует закрытия всех тегов и обязательного использования кавычек для значений атрибутов, например, но такое преобразования позволяет гарантировать корректность отдаваемого посетителю документа и минимизировать возможные проблемы.
Возможно я идеалист, но пока убедительных для меня доводов против использования XHTML я не встречал.
Возможно я идеалист, но пока убедительных для меня доводов против использования XHTML я не встречал.
Ну, неужели я должен был полностью листинг привести? :-D
Я показал пример как привести тэги — это самое сложное из всего перечисленного — все остальное реализуется регспами в пару строчек. Честно :)
Я показал пример как привести тэги — это самое сложное из всего перечисленного — все остальное реализуется регспами в пару строчек. Честно :)
Насколько понимаю, в PHP loadHTML фиксит некорректный html и выдает на выходе корректное DOM-дерево к которому xslt применяется без проблем. По крайней мере распространенные проблемы (отсутствие закрывающих тегов и т.п.) он обрабатывает точно, хотя специально я его не ломал.
В других языках программирования HTML тоже есть библиотеки, способные разобрать «поломанный» HTML и построить корректный DOM.
В других языках программирования HTML тоже есть библиотеки, способные разобрать «поломанный» HTML и построить корректный DOM.
Имхо, тут имеет смысл двигаться от обратного: не описывать исключения, а обрабатывать лишь те элементы, которые нам нужны, посылая всё остальное либо в «мусор» либо в простой текстовый вывод.
Например, у нас таким образом выводится весь контент (как пользовательский, так и редакционный): если в каком-то месте проекта не предполагается вывод ссылок, то неважно, кто их добавил — они будут проигнорированы, и выведется только содержание текста ссылки.
Хотя, у всех задачи разные. И спасибо за rel=«nofollow» — отличное решение. Мне почему-то не приходило в голову, что можно внешним ссылкам ставить этот атрибут. :)
Например, у нас таким образом выводится весь контент (как пользовательский, так и редакционный): если в каком-то месте проекта не предполагается вывод ссылок, то неважно, кто их добавил — они будут проигнорированы, и выведется только содержание текста ссылки.
Хотя, у всех задачи разные. И спасибо за rel=«nofollow» — отличное решение. Мне почему-то не приходило в голову, что можно внешним ссылкам ставить этот атрибут. :)
Исключительно проблема движков, которые зачем–то используют HTML вместо bbCode, Creole и т. п.
Ну, например, diary.ru разрешает использовать html. Многие wysiwyg редакторы отдают на выходе html, а не bbcode. Поэтому я бы не сказал что это проблема только движков. Но и bbcode, к сожалению, не панацея — как он поможет если нужно гибко настроить разрешения — обычные пользователи могут использовать ограниченный набор тегов, модераторы — расширенный, администраторы — без ограничений? Все равно фильтрация в той или иной форме потребуется.
Вот в X-Wiki, которую я применяю, WYSIWIG тоже отдаёт HTML. Ну так его и конвертировать надо в нормальный формат. И конвертируется, и работает. И в IPB 3, и в X-Wiki.
Произвольный HTML и скрипты в X-Wiki тоже можно вставлять, но если его просто так вставить, он при преобразовании в X-Wiki прожуётся и выкинется. В самом редакторе сделаны крючки для плагинов так, чтобы блок, рендерящийся плагином, нельзя было редактировать в WYSIWIG на уровне гипертекста, можно было только редактировать его через меню WYSIWIG. Например, «содержание» или «сноски» — такие блоки, рендерящиеся плагинами, и редактировать их нельзя. HTML — тоже такой блок, и редактирование его напрямую невозможно, можно только в меню редактирования блока зайти и там писать чистый HTML.
bbCode, сколько я его видел, очень замечательно настраивается на права. Несанкционированные теги просто не обрабатываются при показе конечного текста. В некоторых разделах форума нельзя делать гиперссылки — типичный пример. То же и в X-Wiki. Некоторые блоки отображаются только, если страницу написал администратор.
Произвольный HTML и скрипты в X-Wiki тоже можно вставлять, но если его просто так вставить, он при преобразовании в X-Wiki прожуётся и выкинется. В самом редакторе сделаны крючки для плагинов так, чтобы блок, рендерящийся плагином, нельзя было редактировать в WYSIWIG на уровне гипертекста, можно было только редактировать его через меню WYSIWIG. Например, «содержание» или «сноски» — такие блоки, рендерящиеся плагинами, и редактировать их нельзя. HTML — тоже такой блок, и редактирование его напрямую невозможно, можно только в меню редактирования блока зайти и там писать чистый HTML.
bbCode, сколько я его видел, очень замечательно настраивается на права. Несанкционированные теги просто не обрабатываются при показе конечного текста. В некоторых разделах форума нельзя делать гиперссылки — типичный пример. То же и в X-Wiki. Некоторые блоки отображаются только, если страницу написал администратор.
Конструкцию choose-when-otherwise лучше по возможности не применять. На мой взгляд конечно. Т.к. элемент <xsl:template match="..."> уже является кейсом.
Sign up to leave a comment.
Использование XSLT для предотвращения XSS путем фильтрации пользовательского контента