flask中禁用|safe放行用户输入,必须通过jinja2自动转义或html.escape处理;js上下文须用|tojson;url和属性值需区分转义方式;伪协议须源头拦截,并结合csp与白名单清洗。

别用 |safe 放行用户输入
这是Flask项目里最常踩的坑:只要在模板里写 {{ user_input|safe }},Jinja2就彻底放弃转义,<script>alert(1)</script> 会直接执行。默认行为是安全的,{{ user_input }} 已自动转义为文本;|safe 只应在100%可信且已清洗过的富文本场景下使用(比如CMS后台经 bleach.clean() 过滤后的HTML)。临时加个 |safe 调试,上线前务必删掉。
禁止在Python代码里拼接HTML字符串
用 f"<div>{name}</div>" 或 str.format() 构造响应体,等于绕过Jinja2所有防护。哪怕只拼一行,XSS风险就立刻生效。正确路径是:视图函数只传原始数据进 render_template(),把渲染和转义全交给模板引擎。若真需生成HTML(如邮件内容),先调 html.escape(name),再拼接。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
JS上下文必须用 |tojson,不能直接插变量
在 <script></script> 标签或 onclick 属性里写 {{ user_input }},HTML转义完全无效——单引号、反斜杠、 都会破坏JS语法并触发执行。错误示例:<script>var msg = "{{ user_input }}";</script>;正确写法:<script>var msg = {{ user_input | tojson }};</script>。同理,属性值优先用 data-* 自定义属性 + JS读取,比直接塞进 onclick="..." 更可控。
URL和属性值要区分转义方式
HTML转义只处理 、<code>>,但双引号属性里的 "、'、= 同样危险。别写 <a href="https://www.php.cn/link/18c934d7919291237857dfcc1e597c39">;改用 <code><a href="https://www.php.cn/link/b57a9c513abb3bff097f080b51e2f754">。避免把用户数据塞进 <code>id、class 等属性,非用不可时,统一用单引号包裹 + |e(即 escape):<div id="{{ user_id | e }}">。伪协议如 <code>javascript:、data:text/html 必须从输入源头就拦截,不能靠后端转义补救。
真正难防的是那些“看起来不像代码”的输入——比如昵称字段里藏了 onmouseover=alert(1),或 data: 开头的base64 payload。防御不能只靠一层转义,得结合输入过滤、CSP策略和白名单清洗。










