如何配置服务端头信息以仅允许指定脚本访问受会话保护的JSON资源
解决方案:使用Content-Security-Policy(CSP)结合脚本验证
要实现仅允许https://example.com/private/script.js访问私有JSON资源的需求,核心是利用浏览器的Content-Security-Policy (CSP) 机制,限制只有合法脚本能发起对data.json的请求。以下是两种可靠的实现方式:
方法1:脚本哈希验证(适合内容固定的脚本)
如果你的private/script.js内容不会频繁变动,哈希验证是最直接的方案:
- 生成脚本哈希:计算脚本内容的SHA-256哈希(Base64编码)。你可以用命令行工具生成:
openssl dgst -sha256 -binary /path/to/private/script.js | base64 - 配置CSP响应头:服务端在所有页面的HTTP响应中添加以下CSP规则:
规则说明:Content-Security-Policy: connect-src https://example.com/private/data.json; script-src 'sha256-你的哈希值';connect-src:明确仅允许向指定的data.json地址发起连接请求script-src:仅允许执行哈希匹配的脚本(也就是你的private/script.js)
其他位置的脚本因为哈希不匹配,会被浏览器直接阻止执行,自然无法发起fetch请求。
方法2:Nonce随机值验证(适合动态内容的脚本)
如果脚本内容可能动态变化,用一次性随机nonce更灵活:
- 生成随机Nonce:服务端在每次处理页面请求时,生成一个安全的随机字符串(比如用UUID或加密随机函数生成,再Base64编码)。
- 配置CSP响应头:将生成的nonce嵌入CSP规则:
Content-Security-Policy: connect-src https://example.com/private/data.json; script-src 'nonce-你的随机nonce值' 'strict-dynamic'; - 标记合法脚本:在加载
private/script.js的<script>标签中添加对应的nonce属性:
规则说明:<script src="/private/script.js" nonce="你的随机nonce值"></script>'strict-dynamic'(可选):允许合法脚本加载的其他子脚本也拥有执行权限,如果你不需要这个特性可以移除
只有带有正确nonce的脚本会被执行,且仅这些脚本能发起对data.json的请求。
额外的安全增强:Fetch Metadata Headers校验
为了避免浏览器不支持CSP的极端情况,服务端可以同时校验请求的Fetch Metadata Headers:
- 检查
Sec-Fetch-Site是否为same-origin(确保请求来自同域) - 检查
Sec-Fetch-Mode是否为cors(脚本发起的fetch请求通常使用此模式) - 检查
Sec-Fetch-Dest是否为empty(fetch请求的目标类型为空)
如果这些头不符合预期,直接返回403 Forbidden,双重保障拦截非法请求。
为什么CORS头没用?
因为所有脚本都在同一个域名下,CORS的Access-Control-Allow-Origin仅针对跨域请求生效,同域请求浏览器不会校验这个头,所以无法实现同域内的脚本访问限制。
内容的提问来源于stack exchange,提问作者wagoon




