Wagtail配置CSP:保留unsafe-inline遭不安全标记,移除则功能异常
解决Wagtail移除CSP中'unsafe-inline'后的后台报错问题
问题根源
Wagtail管理后台会自动注入包含wagtailConfig的内联脚本,移除'unsafe-inline'后,CSP会阻止这些脚本执行,导致菜单加载失败、控制台抛出wagtailConfig未定义的错误。
方案一:使用Nonce(推荐,可维护性高)
Nonce是每个请求唯一的随机字符串,将其加入CSP规则并绑定到内联脚本上,既能满足CSP安全要求,又能放行合法的内联代码。
- 生成请求级Nonce
创建Django中间件,为每个请求生成唯一nonce:
# your_project/middleware.py import uuid class CSPNonceMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # 生成随机nonce字符串 request.csp_nonce = uuid.uuid4().hex response = self.get_response(request) return response
在settings.py中注册该中间件(放在django.middleware.common.CommonMiddleware之后):
MIDDLEWARE = [ # ... 其他中间件 'django.middleware.common.CommonMiddleware', 'your_project.middleware.CSPNonceMiddleware', # ... django-csp的中间件(如果使用django-csp) 'csp.middleware.CSPMiddleware', ]
- 更新CSP配置
如果使用django-csp包,修改settings.py中的CSP规则,将nonce占位符加入script-src和style-src:
CSP_DEFAULT_SRC = ("'self'",) CSP_SCRIPT_SRC = ("'self'", "'nonce-%(nonce)s'", 'unpkg.com', 'www.googletagmanager.com') CSP_STYLE_SRC = ("'self'", "'nonce-%(nonce)s'") CSP_IMG_SRC = ("'self'", 'data:', 'https://www.google-analytics.com', 'https://releases.wagtail.org') CSP_FRAME_SRC = ("'self'", 'www.youtube-nocookie.com') CSP_OBJECT_SRC = ("'none'",) # 禁用object-src更安全,无需unsafe-eval CSP_CONNECT_SRC = ("'self'", 'releases.wagtail.org/latest.txt', 'www.google-analytics.com')
django-csp会自动从request.csp_nonce获取值,替换%(nonce)s。
- 绑定Nonce到内联脚本
Override Wagtail的基础模板(比如wagtailadmin/base.html),为自动注入的内联脚本添加nonce属性:
{% extends "wagtailadmin/base.html" %} {% block extra_js %} <script nonce="{{ request.csp_nonce }}"> window.wagtailConfig = {{ wagtail_config|safe }}; </script> {{ block.super }} {% endblock %}
方案二:使用哈希值(临时应急,维护成本高)
将控制台报错中给出的内联脚本哈希值加入script-src,放行对应的内联代码:
CSP_SCRIPT_SRC = ("'self'", "'sha256-B2D5xPj6Cqf525g1afhgAHB1ntYV+95Bc11='", 'unpkg.com', 'www.googletagmanager.com')
⚠️ 注意:Wagtail版本更新、静态文件编译变化都会导致哈希失效,需要重新生成哈希值,仅适合临时使用。
其他CSP优化建议
- 移除
img-src中的'unsafe-inline':img-src不需要该规则,改为具体的域名而非宽泛的https: - 将
object-src设为'none':除非有特殊插件需求,否则禁用该来源更安全 - 缩小
script-src/style-src的域名范围:避免使用https:这类宽泛规则,指定具体域名
内容的提问来源于stack exchange,提问作者squidg
相关产品推荐
相关产品推荐

