Jinja2 模板使用 autoescape=False¶
ID: py/jinja2/autoescape-false
Kind: problem
Security severity: 6.1
Severity: error
Precision: medium
Tags:
- security
- external/cwe/cwe-079
Query suites:
- python-security-extended.qls
- python-security-and-quality.qls
如果未对不受信任的输入进行转义,则可能会发生跨站点脚本 (XSS) 攻击。这适用于模板和代码。如果环境将 autoescape 设置为 False,则 jinja2 模板可能容易受到 XSS 攻击。不幸的是,jinja2 默认将 autoescape 设置为 False。在创建 Environment 对象时,将 autoescape 显式设置为 True 将可以防止这种情况。
建议¶
避免将 jinja2 autoescape 设置为 False。Jinja2 提供了函数 select_autoescape 来确保选择正确的自动转义。例如,它可以在创建环境时使用 Environment(autoescape=select_autoescape(['html', 'xml'])
示例¶
以下示例是一个最小的 Flask 应用程序,它展示了安全和不安全的方式将给定的姓名渲染回页面。第一个视图是不安全的,因为 first_name 未转义,导致页面容易受到跨站点脚本攻击。第二个视图是安全的,因为 first_name 被转义,所以它不容易受到跨站点脚本攻击。
from flask import Flask, request, make_response, escape
from jinja2 import Environment, select_autoescape, FileSystemLoader
app = Flask(__name__)
loader = FileSystemLoader( searchpath="templates/" )
unsafe_env = Environment(loader=loader)
safe1_env = Environment(loader=loader, autoescape=True)
safe2_env = Environment(loader=loader, autoescape=select_autoescape())
def render_response_from_env(env):
name = request.args.get('name', '')
template = env.get_template('template.html')
return make_response(template.render(name=name))
@app.route('/unsafe')
def unsafe():
return render_response_from_env(unsafe_env)
@app.route('/safe1')
def safe1():
return render_response_from_env(safe1_env)
@app.route('/safe2')
def safe2():
return render_response_from_env(safe2_env)
参考资料¶
Jinja2: API.
维基百科: 跨站点脚本.
OWASP: XSS (跨站点脚本) 防护备忘单.
常见漏洞枚举: CWE-79.