在烧瓶中禁用autoescape [英] disabling autoescape in flask
问题描述
\\\
。所以我做了: 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 ,因为它将渲染问题(在
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屋!