gatsby-plugin-csp的script-src能否同时配置unsafe-inline与unsafe-eval
核心结论
- 完全可以在同一个
script-src指令中同时配置'unsafe-inline'和'unsafe-eval',二者不存在冲突,CSP规范本身就支持在同一条指令下声明多个关键字。 - 绝对不要写多个同名的
script-src配置项:你写的第二种方案是完全无效的,因为JS对象中同名key会被最后一个声明的值覆盖,最终插件拿到的只有带'unsafe-eval'的那条规则,'unsafe-inline'配置会直接丢失。
你当前配置报错的原因
1. 第三方脚本域名配置不全
你配置的script-src里只添加了www.example.com,但被拦截的脚本是embed.example.com下的资源。CSP的源匹配规则是精确匹配子域名,不会自动匹配同主域下的其他子域:
- 配置
www.example.com仅允许www.example.com下的脚本加载 - 要允许
embed.example.com需要单独添加该域名,或者写*.example.com匹配所有子域(注意*.example.com不会匹配example.com根域,需要的话要单独加)
2. 内联脚本被拦截是因为哈希规则覆盖了'unsafe-inline'
你开启了mergeScriptHashes: true配置,gatsby-plugin-csp会自动给构建阶段识别到的所有内联脚本计算SHA256哈希,追加到script-src规则里。
按照CSP规范:当
script-src中存在有效的脚本哈希(hash)或随机数(nonce)时,现代浏览器会直接忽略'unsafe-inline'关键字,仅允许哈希/nonce匹配的内联脚本执行。
如果你的站点存在运行时动态插入的内联脚本(比如第三方统计、广告SDK动态插入的内联代码),这些脚本不在构建阶段的识别范围内,没有对应的哈希值,就会被拦截。
3. 关键字顺序不影响规则生效
你调整'unsafe-inline'和'unsafe-eval'的顺序没有任何作用,CSP指令内的关键字和源顺序不影响最终匹配逻辑。
可参考的修正配置
// In your gatsby-config.js module.exports = { plugins: [ { resolve: `gatsby-plugin-csp`, options: { disableOnDev: true, reportOnly: false, mergeScriptHashes: false, // 如果要全局开启unsafe-inline就关掉自动哈希,避免覆盖规则 mergeStyleHashes: true, mergeDefaultDirectives: true, directives: { // 把需要的所有域名都加全,两个unsafe关键字放在同一条规则里 "script-src": "'self' 'unsafe-inline' 'unsafe-eval' www.example.com embed.example.com", "style-src": "'self' 'unsafe-inline'", "img-src": "'self' data: www.google-analytics.com" } } } ] };
如果不想完全关闭哈希合并,也可以保持mergeScriptHashes: true,把被拦截的动态内联脚本的哈希值手动加到script-src里,安全性比直接开'unsafe-inline'更高。
内容的提问来源于stack exchange,提问作者mardag
相关产品推荐
相关产品推荐

