在Jinja有一个安全的替代品吗?

时间:2017-08-08 22:30:38

标签: python escaping jinja2 code-injection pelican

我在使用pelican时发现了这种行为:

Template('<p>{{text|striptags|striptags}}</p>').render(text='&lt;script src="http://chezsoi.org"/&gt;')

呈现为:

<script src="http://chezsoi.org"/>

我指望striptags输出没有任何HTML标记,这是错误的。 因此,我的问题是:内置striptags过滤器是否有“更安全”的替代方案?

我知道快速解决方案是将呼叫链接到striptags

'{{ <p>text|striptags|striptags|striptags }}</p>'

但是如果攻击者可以控制text内容,他们可以对字符串进行双重HTML转义,依此类推。

2 个答案:

答案 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>&lt;script src=&#34;http://chezsoi.org&#34;/&gt;</p>'

>>> template.render(text='&lt;script src="http://chezsoi.org"/&gt;')
u'<p>&amp;lt;script src=&#34;http://chezsoi.org&#34;/&amp;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,
}

并且不要忘记相应地修改模板。删除striptagsescape之类的过滤器以避免两次转义,并将safe过滤器添加到某些不应转义的输出点:

{{ article.content | safe }}

如果不确定,请保留生成的静态文件的原始版本,然后与之比较以查看更改之处。