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



