首页 文章

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

提问于
浏览
11

我正在尝试清理和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只提到了实体的解析,而不是它们的产生 . 当然我可以在所有节点上运行替换,但由于我可能会错过一些东西,我宁愿让一些经过测试和测试的代码完成这项工作 .

Why doesn't Beautiful Soup escape < (and other magic characters) by default, and how do I make it do that?


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

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

2 回答

  • 2

    我知道在原始问题之后这是3.5yrs,但您可以使用formatter='html' argument to prettify(), encode(), or decode()生成格式良好的HTML .

  • 6

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

相关问题