在烧瓶中禁用autoescape [英] disabling autoescape in flask

查看:142
本文介绍了在烧瓶中禁用autoescape的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  footext =f 
$ b $

#footext ==f\\\
o\\\
o

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

bar.html:

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

然而autoescape是启用的,我看到的是 f
> o< br /> o
。另外我的方法是不安全的,我希望除了< br /> 之外的所有标签都可以从文本中转义出来。我看了一下flask.Markup模块,然而他们也没有真正的工作。



有什么方法可以做到这一点? 是您可以采取的两种合理的方法。解决方案1当您将不安全的输入与HTML结合成一个单变量 flask.Markup 实际上是一个非常方便的方法。基本的想法是把你的文本分割成换行符,确保你的HTML转义了你不信任的每一行,然后把它们连接在一起<> 标签,你信任。



这是完整的应用程序来演示这一点。它使用与你的问题相同的 bar.html 模板。请注意,我已经为脚本添加了一些不安全的HTML,以此来说明为什么关闭自动转义功能而不是是解决您的问题的安全解决方案。 / b>

  import flask 

app = flask.Flask(__ name__)

footext =f
o
< script> alert('oops')< / script>
o


@ app.route(/ foo)
def foo():
text =
for footext.split('\\\
'):
text + = flask.Markup.escape(line)+ flask.Markup('< br />')
return flask.render_template(bar.html,text = text)

if __name__ ==__main__:
app.run(debug = True)


$ b

解决方案

2

另一个选择是将复杂性推送到您的模板中,为您留下更简单的视图。只需将 footext 分割成几行,然后就可以在模板中循环,自动填充将保证安全。



简单的看法:
$ b

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

模板bar.html变成:

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



结论



我个人比较喜欢解决方案2 ,因为它将渲染问题(在< br /> 标记之间用行分隔)放在它们所属的模板中。如果你以后想要改变这个,比如说,在一个项目符号列表中显示行,你只需要改变你的模板,而不是你的代码。


I want to show some text to the user. the string variable I'm sending has multiple newline characters and I dont want \n to be displayed. so I did:

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>

However autoescape is enabled and what I see is f<br />o<br />o. Also my method isn't safe, I want every tag except <br /> to be escaped from the text. I took a look at flask.Markup module and however they don't really work either.

What is the proper way to do this?

解决方案

There are two reasonable approaches you could take.

Solution 1

As you are combining unsafe input with HTML into a single variable flask.Markup is actually quite a handy way to do this. Basic idea is to split your text on the newline characters, make sure you HTML escape each of the lines which you do not trust, then glue them back together joined by <br /> tags which you do trust.

Here's the complete app to demonstrate this. It uses the same bar.html template as in your question. Note that I've added some unsafe HTML to the footext as a demonstration of why turning off autoescaping is not a safe solution to your problem.

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)

Solution 2

Another option would be to push the complexity into your template, leaving you with a much simpler view. Just split footext into lines, then you can loop over it in your template and autoescaping will take care of keeping this safe.

Simpler view:

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

Template bar.html becomes:

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

Conclusion

I personally prefer solution 2, because it puts the rendering concerns (lines are separated by <br /> tags) in the template where they belong. If you ever wanted to change this in future to, say, show the lines in a bulleted list instead, you'd just have to change your template, not your code.

这篇关于在烧瓶中禁用autoescape的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆