SRI校验生效必须同时配置integrity和crossorigin属性,缺一则静默跳过;哈希须基于真实CDN响应体计算,仅script和link[rel=stylesheet]支持,且CDN需返回Access-Control-Allow-Origin响应头。

integrity 属性是实现 SRI(子资源完整性)的核心手段,但它本身不自动生效——必须配合正确配置才能真正拦住 CDN 劫持。单独加 integrity,浏览器大概率会静默忽略,资源照常加载,风险一点没降。
integrity 和 crossorigin 必须成对出现
浏览器只在 CORS 模式下才会读取并校验 integrity 值。只要没写 crossorigin,或写错(比如 crossorigin="true"),校验就根本不会启动,控制台也不会报错,只会安静加载被篡改的脚本或样式。
- 公开 CDN(如 jsDelivr、cdn.jsdelivr.net、unpkg)一律用
crossorigin="anonymous" - 如果资源需携带 Cookie(极少见),才用
crossorigin="use-credentials",且服务端必须返回Access-Control-Allow-Credentials: true和明确的Access-Control-Allow-Origin(不能是*) -
<script src="xxx.js" integrity="sha384-..."></script>这样漏掉 crossorigin 的写法,等于没加 SRI
哈希值必须从真实 CDN 响应体计算
本地文件、网页源码里抄来的哈希、在线生成器算的值,99% 不可用。CDN 可能重定向、压缩(gzip/Brotli)、加 BOM、甚至按 UA 返回不同内容,这些都会让哈希不匹配。
- 可靠命令:
curl -sL https://cdn.jsdelivr.net/npm/react@18/umd/react.production.min.js | openssl dgst -sha384 -binary | openssl base64 -A - 必须加
-sL:静默 + 跟随重定向,否则可能哈希的是 302 响应 - 不要手动解压或加
--compressed:curl 默认已处理压缩,返回的就是浏览器实际收到的字节 - 算法优先选
sha384:比 sha256 更抗碰撞,主流 CDN 全支持;sha512浏览器不认(即使写了也静默跳过)
CSP 策略必须显式放行 CDN 域名
SRI 只负责“校验”,CSP 才决定“能不能发请求”。如果 CSP 的 script-src 或 style-src 没列 CDN 域名,浏览器连请求都不会发——SRI 根本没机会工作。
- 错误写法:
script-src 'self'→ 即使加了 integrity,也会报Refused to load script from 'https://cdn.example.com' - 正确写法:
script-src 'self' https://cdn.jsdelivr.net https://unpkg.com - 禁用通配符
https::Chrome 94+ 已废弃,不推荐 - 子域名泛支持可写
https://*.example.com,但前提是所有子域名都配了Access-Control-Allow-Origin: *
CDN 必须返回正确的 CORS 响应头
就算你写了 crossorigin="anonymous",如果 CDN 响应头里没有 Access-Control-Allow-Origin: *(或你的域名),浏览器拿不到完整响应体,SRI 校验会直接跳过。
- 用
curl -I https://cdn.example.com/lib.js检查响应头,确认含Access-Control-Allow-Origin - 老旧镜像站、内网私有 CDN 常缺失该头,此时要么换 CDN,要么加代理层补头
- 部分 CDN 对字体(
font)、图片等资源不返回 CORS 头,SRI 在这些资源上天然不生效

















