Flask Talisman CSP配置异常:内联脚本与样式执行被阻止
解决方案
1. 正确配置CSP:结合Nonce与外部资源源
你的核心问题是CSP未同时兼顾外部CDN资源放行和内联内容授权,同时存在域名拼写错误。以下是修正后的完整配置:
import os from flask import Flask, render_template from flask_talisman import Talisman app = Flask(__name__) # 生成唯一nonce,每个请求都要重新生成 def generate_nonce(): return os.urandom(16).hex() # CSP配置:包含外部源 + nonce占位符(Talisman会自动替换为实际值) csp = { 'default-src': "'self'", 'script-src': [ "'self'", "'nonce-{nonce}'", "https://cdn.jsdelivr.net/npm/", "https://www.googletagmanager.com", "https://www.google.com/recaptcha/", "https://www.gstatic.com/recaptcha/" ], 'frame-src': [ "https://www.google.com/recaptcha/", "https://recaptcha.google.com/recaptcha/" # 修正原域名拼写错误 ], 'style-src': [ "'self'", "'nonce-{nonce}'", "https://cdn.jsdelivr.net/npm/" ], 'object-src': "'none'" } # 初始化Talisman,指定nonce需要注入的指令 Talisman( app, content_security_policy=csp, content_security_policy_nonce_in=['script-src', 'style-src'] )
2. 路由中传递Nonce到模板
确保每个请求生成唯一nonce并传入模板:
@app.route('/') def index(): nonce = generate_nonce() return render_template('index.html', nonce=nonce)
3. 模板中给内联内容添加Nonce
所有内联脚本、内联样式(包括元素的style属性)必须添加nonce="{{ nonce }}",外部CDN资源只要CSP配置了域名就无需额外操作:
<!-- 外部Bootstrap CSS --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"> <!-- GTM外部脚本 --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script> <!-- GTM内联初始化脚本,必须加nonce --> <script nonce="{{ nonce }}"> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-XXXXXXXXXX'); </script> <!-- ReCaptcha --> <script src="https://www.google.com/recaptcha/api.js" async defer></script> <div class="g-recaptcha" data-sitekey="你的sitekey"></div> <!-- 自定义内联脚本 --> <script nonce="{{ nonce }}"> // 你的内联JS代码 console.log("内联脚本测试"); </script> <!-- 自定义内联样式 --> <style nonce="{{ nonce }}"> .custom-box { padding: 10px; border: 1px solid #ccc; } </style> <!-- 带内联style属性的元素 --> <div style="margin-top: 20px;" nonce="{{ nonce }}">测试内容</div>
4. 可选:用哈希放行特定内联内容
如果不想用nonce,可直接使用浏览器错误提示中的哈希值放行对应内联内容(缺点是内联内容修改后哈希会失效):
csp = { 'script-src': [ # ... 其他源 "'sha256-h0FtDBdxOnu72uVQe4oUILMiGyexQqDT1jgToPa4Sog='" # 错误提示中的脚本哈希 ], 'style-src': [ # ... 其他源 "'sha256-pyVP/WTBWg0xeYb2xYVwRtZnbyqX6sWurV0uPjEvCN8='" # 错误提示中的样式哈希 ] }
内容的提问来源于stack exchange,提问作者Pyenb
相关产品推荐
相关产品推荐

