Flask编写CSP上报路由遇CSRF错误返回400如何解决?
Flask CSP违规上报路由400 CSRF错误解决方案
出现该错误的核心原因是:浏览器自发发送的CSP违规上报请求不会携带站点生成的CSRF令牌,被全局开启的Flask-WTF CSRF校验拦截。你只需要给CSP上报路由单独豁免CSRF校验即可解决问题,具体实现方法如下:
方法1:使用@csrf.exempt装饰器单独豁免路由
如果你已经给全站开启了Flask-WTF的CSRF全局保护,直接给CSP上报路由添加豁免装饰器即可,示例代码如下:
from flask import Flask, request from flask_wtf.csrf import CSRFProtect from flask_talisman import Talisman import json app = Flask(__name__) app.config["SECRET_KEY"] = "替换为你的实际密钥" # 全局开启CSRF保护 csrf = CSRFProtect(app) # 配置Talisman CSP规则,指定上报地址 Talisman( app, content_security_policy={ "default-src": "'self'", "script-src": "'self'", "report-uri": "/csp-report", } ) # 给CSP上报路由添加CSRF豁免装饰器 @app.route("/csp-report", methods=["POST"]) @csrf.exempt def csp_report_handler(): # 适配浏览器上报的application/csp-report类型请求 if request.content_type == "application/csp-report": csp_data = json.loads(request.get_data(as_text=True)) else: csp_data = request.get_json() # 此处可添加上报数据的存储、日志记录逻辑 app.logger.warning("收到CSP违规上报:%s", csp_data) # CSP上报规范要求返回204空响应 return "", 204
注意事项
- 不要随意给涉及用户数据提交的业务路由添加CSRF豁免,仅给这类浏览器/第三方服务自发调用的回调类路由开豁免,避免引入CSRF攻击风险。
- 若你需要批量豁免多个同前缀的路由,可以在初始化
CSRFProtect时通过exempt_views参数批量指定,也可以通过app.config["WTF_CSRF_EXEMPT_METHODS"]配置指定不需要校验的请求方法,但不推荐修改全局配置,单独给上报路由加装饰器安全性最高。
内容的提问来源于stack exchange,提问作者jshwi
相关产品推荐
相关产品推荐

