Django-CSP在Bootstrap模态框中失效,独立页面正常的问题求助
Django-CSP 异常问题:Bootstrap模态框加载时失效,独立页面正常
核心问题
通过Bootstrap模态框加载Django视图/模板时,django-csp配置失效;但该视图作为独立页面加载时CSP可正常工作。
相关代码
模板中的Script标签
<script nonce="{{ CSP_NONCE }}" src="{% static 'js/mmImport.js' %}" defer data-mmimporturl="{% url 'mmImport' %}"> </script>
Settings.py中的CSP配置
MIDDLEWARE = [ 'csp.middleware.CSPMiddleware' # 其他中间件... ] # Content Security Policy CSP_DEFAULT_SRC = ("'self'") CSP_IMG_SRC = ("'self'") CSP_STYLE_SRC = ("'self'") CSP_SCRIPT_SRC = ("'self'") CSP_INCLUDE_NONCE_IN = ('script-src')
场景对比
- 模态框加载场景:仅保留上述CSP策略时,控制台报错:
仅当[Error] Refused to execute a script because its hash, its nonce, or 'unsafe-inline' does not appear in the script-src directive of the Content Security Policy. (mmHomepage, line 0)script-src添加'unsafe-inline'时才能正常运行。 - 独立页面加载场景:使用上述CSP策略无报错,运行正常。
已尝试的方法
- 将JS代码直接写入模板而非引入外部文件,仍出现相同错误;
- 用
@method_decorator(csp_exempt)豁免首页视图CSP后,模态框内JS可正常运行,但豁免模态框视图CSP无效,推测是首页CSP策略覆盖了模态框内容。
临时解决方案
在CSP_SCRIPT_SRC中添加'strict-dynamic':
CSP_SCRIPT_SRC = ("'self'", "'strict-dynamic'")
但此方案要求所有script标签必须携带nonce,并非理想选择。
针对性解决方案
1. 确保模态框内容的Nonce一致性
模态框通过AJAX加载到首页时,首页的CSP nonce和模态框模板渲染生成的nonce可能不一致。需保证模态框使用当前页面(首页)的nonce:
- 若模态框是模板片段渲染后插入首页,需在首页渲染时将
CSP_NONCE传递给模态框模板; - 若通过AJAX请求加载模态框内容,需在请求头中携带首页的nonce,后端视图将该nonce传入模态框模板,而非让django-csp自动生成新nonce。
2. 调整CSP策略适配模态框加载模式
如果无法保证nonce一致性,可针对首页添加特定规则:
- 若模态框内JS是静态资源,计算该资源的哈希值(如用
openssl dgst -sha256 -binary js/mmImport.js | base64),将哈希值加入配置:CSP_SCRIPT_SRC = ("'self'", "'sha256-xxxxxx...xxxxxx'") - 若存在内联JS,将内联代码的哈希值加入
CSP_SCRIPT_SRC,替代'unsafe-inline'。
3. 重构模态框加载逻辑
如果上述方案仍不适用,可考虑:
- 将模态框的JS逻辑整合到首页主JS文件中,避免动态加载额外脚本;
- 使用Django模板继承,将模态框内容作为首页的一部分提前渲染,而非动态加载,确保nonce统一。
内容的提问来源于stack exchange,提问作者Chef Codev
相关产品推荐
相关产品推荐

