Как заставить Beautiful Soup выводить HTML-сущности? - PullRequest
11 голосов
/ 10 сентября 2010

Я пытаюсь очистить и XSS-защиту некоторого ввода HTML от клиента. Я использую Python 2.6 с Beautiful Soup. Я анализирую входные данные, удаляю все теги и атрибуты, не входящие в белый список, и преобразую дерево обратно в строку.

Однако ...

>>> 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 упоминается только разбор сущностей, а не их создание. Конечно, я могу выполнить замену на всех NavigableString узлах, но, поскольку я могу что-то пропустить, я бы предпочел, чтобы какой-то проверенный и протестированный код выполнил эту работу.

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


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

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

Ответы [ 2 ]

6 голосов
/ 28 марта 2014

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

2 голосов
/ 10 сентября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...