Подтвердить что ты не робот

Как сделать красивые суп-выходные объекты HTML?

Я пытаюсь дезинфицировать и XSS-защищать некоторые HTML-данные от клиента. Я использую Python 2.6 с красивым супом. Я анализирую ввод, разделяю все теги и атрибуты не в белом списке и преобразую дерево обратно в строку.

Однако...

>>> unicode(BeautifulSoup('text < text'))
u'text < text'

Это не похоже на действительный HTML-код для меня. И с моим стриптизером тегов он открывает путь к разным гадостям:

>>> print BeautifulSoup('<<script></script>script>alert("xss")<<script></script>script>').prettify()
<
<script>
</script>
script>alert("xss")<
<script>
</script>
script>

Партии <script></script> будут удалены, а остальное - это не только атака XSS, но даже допустимый HTML.

Очевидным решением является замена всех символов < на &lt;, которые после разбора обнаруживаются не принадлежащими тегу (и аналогичным для >&'"). Но Beautiful Soup documentation упоминает только разбор сущностей, а не их создание. Конечно, я могу запустить замену на все узлы NavigableString, но, поскольку я могу что-то пропустить, я бы предпочел, чтобы какой-то проверенный и проверенный код выполнил эту работу.

Почему по умолчанию не исчезает Beautiful Soup < (и другие магические символы), и как это сделать?


N.B. Я также посмотрел на lxml.html.clean. Кажется, он работает на основе черного списка, а не белого списка, поэтому для меня это не очень безопасно. Теги могут быть в белом списке, но атрибуты не могут, и это позволяет слишком много атрибутов для моего вкуса (например, tabindex). Кроме того, он дает AssertionError на входе <SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>. Нехорошо.

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

4b9b3361

Ответ 1

Я знаю, что это 3.5yrs после вашего исходного вопроса, но вы можете использовать аргумент formatter='html' для prettify(), encode() или decode() для создания хорошо сформированного HTML.

Ответ 2

Класс lxml.html.clean.Cleaner позволяет вам предоставлять белый список тегов с аргументом allow_tags и использовать белый список атрибутов precomputed из feedparser с аргументом safe_attrs_only. И lxml определенно обрабатывает сущности правильно при сериализации.