您可以采取两种合理的方法。
解决方案 1
当您将不安全的输入与 HTML 组合到一个变量flask.Markup
中时,实际上是一种非常方便的方法。<br />
基本思想是将文本拆分为换行符,确保 HTML 转义您不信任的每一行,然后通过您信任的标签将它们粘合在一起。
这是演示这一点的完整应用程序。它使用与bar.html
您的问题相同的模板。请注意,我在 中添加了一些不安全的 HTML,footext
以演示为什么关闭自动转义不是解决您的问题的安全解决方案。
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,因为它将渲染问题(行由<br />
标签分隔)放在它们所属的模板中。如果您以后想更改它,例如,在项目符号列表中显示行,您只需要更改您的模板,而不是您的代码。