0

我使用 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 代码而不让漏洞通过吗?

4

1 回答 1

1

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

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 版本?

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

于 2013-03-20T15:54:28.397 回答