我在使用pelican时发现了这种行为:
Template('<p>{{text|striptags|striptags}}</p>').render(text='<script src="http://chezsoi.org"/>')
呈现为:
<script src="http://chezsoi.org"/>
我指望striptags
输出没有任何HTML标记,这是错误的。
因此,我的问题是:内置striptags
过滤器是否有“更安全”的替代方案?
我知道快速解决方案是将呼叫链接到striptags
:
'{{ <p>text|striptags|striptags|striptags }}</p>'
但是如果攻击者可以控制text
内容,他们可以对字符串进行双重HTML转义,依此类推。
答案 0 :(得分:1)
我非常确定striptags
过滤器用于“美学”删除标签(清理数据以获得纯文本),但不是作为防水安全措施。
在安全性(防止XSS)方面,您应该使用Jinjas HTML escaping features。
您可以使用|escape
过滤器(别名:|e
)手动转义HTML,也可以使用Environment
并启用Jinja的 autoescaping :
>>> env = Environment(autoescape=True)
>>> template = env.from_string('<p>{{text}}</p>')
>>> template.render(text='<script src="http://chezsoi.org"/>')
u'<p><script src="http://chezsoi.org"/></p>'
>>> template.render(text='<script src="http://chezsoi.org"/>')
u'<p>&lt;script src="http://chezsoi.org"/&gt;</p>
另请参阅Flask文档中的Security Considerations部分 - 由于这个原因,Flask打开了Jinja的自动转换,以防止XSS。
Jinja将来likely make autoescaping the default:
<强> Autoescaping 强>
[...]但默认情况下尚未启用自动转换,但这很可能在将来发生变化
关于自动调节的说明
在Jinja2的未来版本中,出于安全原因,我们可能默认启用自动加载。因此,我们鼓励您立即显式配置自动转换,而不是依赖于默认值。
答案 1 :(得分:1)
Pelican默认情况下不启用Jinja的autoescape
(到目前为止,版本4.5.1),我认为这不是一个好主意。文章的标题和摘要不应包含<
>
之类的字符,否则您将无法获得正确的输出结果。对于主题编码器,它不方便,并且容易出现错误。实际上,应该仅输出很少的变量,而在输出时应该对大多数变量进行编码。
您可以在配置文件中启用它:
JINJA_ENVIRONMENT = {
'autoescape': True,
}
并且不要忘记相应地修改模板。删除striptags
和escape
之类的过滤器以避免两次转义,并将safe
过滤器添加到某些不应转义的输出点:
{{ article.content | safe }}
如果不确定,请保留生成的静态文件的原始版本,然后与之比较以查看更改之处。