lxml清理器忽略base64图像

时间:2013-03-13 13:23:35

标签: python security lxml

我使用lxml.html.clean删除我的html代码中的不受信任的输入。我意识到lxml会删除代码中的data:标记。但是我想以base64格式插入图像(从数据库中,我没有文件)所以我需要这个标签。例如,参加

from lxml.html.clean import Cleaner
cleaner = Cleaner()
cleaner.clean_html("""
    <img src="http://test.com/img.png"/>
    <img src="data:image/png;base64,aGVsbG8="/>
""")

结果是'<span><img src="http://test.com/img.png"><img src=""></span>'。第一张图片没有转义,第二张是。

任何想法如何让它接受我的base64代码而不让漏洞通过?

1 个答案:

答案 0 :(得分:1)

安装lxml 3.1.0后,我能够重现这种行为。 这是基于“猴子修补”的解决方案 - 替换lxml.html.clean模块中的查找正则表达式模式,以排除具有数据的链接:image /.*; base64 from removal。

import re
import lxml
from lxml.html.clean import Cleaner
new_pattern = '\s*(?:javascript:|jscript:|livescript:|vbscript:|data:[^(?:image/.+;base64)]+|about:|mocha:)'

print(new_pattern)

lxml.html.clean._javascript_scheme_re = re.compile(new_pattern, re.I)


cleaner = Cleaner()
dochtml = """
    <img src="http://test.com/img.png"/>
    <img src="data:image/png;base64,aGVsbG8="/>
    <img src="data:unsafe/contents;base64,aGVsbG8="/>
    <img src="data:text/html;base64,PGh0bWw+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPmFsZXJ0KC‌​doaScpPC9zY3JpcHQ+PC9odG1sPg=="/>
"""
r = cleaner.clean_html(dochtml)
print(r)

结果

<span><img src="http://test.com/img.png">
    <img src="data:image/png;base64,aGVsbG8=">
    <img src="">
    <img src="">
</span>

它的缺点 - 它依赖于内部变量名称,这在Cleaner的公共界面中没有公布。因此,模块开发人员可以更改变量的名称或改进其正则表达式的版本。

为了安全起见,我会在Web服务器上创建URL处理程序,以便通过id将图像内容从数据库中返回。所以在你的HTML文档中,它就像这样<img src="http://myserver/showimg?id=123213">。但是这将涉及添加许多额外的移动部件 - 比如拥有网络服务器等。如果全世界都不希望能够访问这些图像,那么它将无法工作。

旧回答:

应该可以配置Cleaner以保留这些标签,但我无法重现您的情况 - 它只适用于我。我正在使用python 2.7.2和lxml 2.2.8 win-32。 请说明你有什么python和lxml版本?

我尝试运行您的示例并获取未删除的第二个图像标记内容