如何制作美丽的汤输出HTML实体?

时间:2010-09-10 11:29:00

标签: python html xss beautifulsoup

我正在尝试清理和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 documentation只提到实体的解析,而不是生成它们。当然,我可以在所有NavigableString节点上运行替换,但由于我可能会遗漏某些内容,我宁愿让一些经过验证的代码完成这项工作。

默认情况下,为什么美丽的汤不会逃脱<(以及其他魔术角色),我该怎么做呢?


N.B。我也看了lxml.html.clean。它似乎是在黑名单的基础上工作,而不是白名单,所以它对我来说似乎不太安全。标签可以列入白名单,但属性不能,并且它允许我的品味太多属性(例如tabindex)。此外,它在输入AssertionError上提供<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>。不好。

其他清理HTML方法的建议也非常受欢迎。我不是世界上唯一尝试这样做的人,但似乎没有标准的解决方案。

2 个答案:

答案 0 :(得分:6)

我知道这是原始问题后的3。5年,但您可以使用formatter='html' argument to prettify(), encode(), or decode()生成结构良好的HTML。

答案 1 :(得分:2)

lxml.html.clean.Cleaner类允许您使用allow_tags参数提供标记白名单,并使用带有safe_attrs_only参数的feedparser中的预计算属性白名单。并且lxml肯定会在序列化时正确处理实体。