给违反CSP 'unsafe-eval'规则的第三方脚本添加nonce后仍报错如何解决?
问题原因
- 核心原因:
nonce仅用于校验静态内联/外部脚本的加载权限,无法覆盖运行时动态执行字符串代码的行为。你遇到的EvalError是因为netlify-cms的代码用到了eval()、new Function(代码字符串)、setTimeout("代码字符串")这类需要unsafe-eval权限的API,这类操作的权限和脚本是否带nonce无关。 - 潜在校验问题:你给出的示例中,script标签上的nonce值和响应头CSP里的nonce值并不一致,建议先确认生产环境中两个值是否真的完全匹配。如果值不匹配,首先检查nginx配置:
set_secure_random_alphanum $cspNonce是否只在当前server/location块执行一次,sub_filter和add_header逻辑是否属于同一个上下文,避免nonce被重复生成导致不匹配。
解决方案
方案一:直接允许unsafe-eval(推荐,改动最小)
直接在你的CSP script-src 指令中添加'unsafe-eval'即可,修改nginx配置如下:
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-$cspNonce' 'unsafe-eval' 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=' petstore.swagger.io;connect-src 'self' petstore.swagger.io";
该方案适合内部使用、对CSP安全要求没有达到金融级的场景,也是大部分使用netlify-cms的站点的通用解法。
方案二:移除所有eval相关逻辑(适合安全要求极高的场景)
如果你不允许在CSP中添加'unsafe-eval',需要修改netlify-cms的源码,替换所有用到动态执行字符串代码的逻辑:
- 把所有
eval(xxx)替换为对应的静态实现 - 把所有
new Function("代码字符串")的调用改为静态函数声明 - 把所有
setTimeout("代码字符串")、setInterval("代码字符串")改为传入函数而非字符串
该方案改动成本较高,需要你对netlify-cms的依赖、源码逻辑有足够的了解。
内容的提问来源于stack exchange,提问作者dagda1
相关产品推荐
相关产品推荐

