【问题标题】:disabling autoescape in flask在烧瓶中禁用自动转义
【发布时间】:2013-01-29 21:23:28
【问题描述】:

我想向用户显示一些文本。我发送的字符串变量有多个换行符,我不想显示\n。所以我做了:

footext = """f
o
o"""

#footext == "f\no\no"

@app.route("/someurl")
def foo():
    return render_template("bar.html", text = footext.replace("\n", "<br />"))

bar.html:

<html>
{{ text }}
</html>

但是自动转义已启用,我看到的是f&lt;br /&gt;o&lt;br /&gt;o。我的方法也不安全,我希望除&lt;br /&gt; 之外的每个标签都从文本中转义。我看了一下flask.Markup 模块,但是它们也没有真正起作用。

这样做的正确方法是什么?

【问题讨论】:

    标签: python flask


    【解决方案1】:

    您可以采取两种合理的方法。

    解决方案 1

    当您将不安全输入与 HTML 组合到单个变量中时,flask.Markup 实际上是一种非常方便的方法。基本的想法是在换行符上分割你的文本,确保你 HTML 转义你不信任的每一行,然后用你信任的 &lt;br /&gt; 标签将它们粘在一起。

    这是演示这一点的完整应用程序。它使用与您的问题相同的 bar.html 模板。请注意,我在 footext 中添加了一些不安全的 HTML,以说明为什么关闭自动转义不是解决您的问题的安全方法。

    import flask
    
    app = flask.Flask(__name__)
    
    footext = """f
    o
    <script>alert('oops')</script>
    o"""
    
    
    @app.route("/foo")
    def foo():
        text = ""
        for line in footext.split('\n'):
            text += flask.Markup.escape(line) + flask.Markup('<br />')
        return flask.render_template("bar.html", text=text)
    
    if __name__ == "__main__":
        app.run(debug=True)
    

    解决方案 2

    另一种选择是将复杂性推入您的模板中,从而为您提供更简单的视图。只需将footext 拆分成行,然后您就可以在模板中对其进行循环,自动转义将负责确保其安全。

    更简单的视图:

    @app.route("/foo")
    def foo():
        return flask.render_template("bar.html", text=footext.split('\n'))
    

    模板 bar.html 变为:

    <html>
        {%- for line in text -%}
            {{ line }}
            {%- if not loop.last -%}
                <br />
            {%- endif -%}
        {%- endfor -%}
    </html>
    

    结论

    我个人更喜欢解决方案 2,因为它将渲染问题(行由 &lt;br /&gt; 标签分隔)放在它们所属的模板中。如果您以后想更改此设置,例如,改为在项目符号列表中显示行,您只需要更改您的模板,而不是您的代码。

    【讨论】:

    • 你回答的后半部分正是我的想法。
    • 这也是我的首选解决方案。我添加了一个结论来说明这一点,并解释原因。
    【解决方案2】:

    我将把my previous answer 作为一个的例子。

    这种事情的一个很好的解决方案是custom filter,它可以让你使用像

    这样的语法
    {{ block_of_text | nl2br }}
    

    您可以方便地使用this nl2br filter snippet(或轻松自定义)!

    【讨论】:

      【解决方案3】:

      在 Jinja2 模板中转autoescaping off,或使用raw block

      【讨论】:

      • 这不安全。问题指出“我的方法不安全,我希望除 &lt;br /&gt; 之外的每个标签都从文本中转义”,所以这将是一个 XSS 漏洞。
      • 你是对的——我没有仔细阅读这个问题;请参阅我的第二个答案以获得更好的解决方案。
      • 我想知道如何关闭自动转义,文档链接为我节省了一些时间。
      猜你喜欢
      • 2019-07-19
      • 2021-05-20
      • 1970-01-01
      • 1970-01-01
      • 2013-02-24
      • 2014-12-07
      • 1970-01-01
      • 2015-09-17
      • 2012-06-16
      相关资源
      最近更新 更多