SRI 子资源完整性是什么?前端什么时候需要使用?
简化版
SRI 是浏览器校验外部脚本或样式内容哈希的机制,通过 integrity 属性确保加载到的资源和预期内容一致。它常用于 CDN、第三方静态资源和供应链防护,能降低资源被篡改后执行恶意代码的风险。
详细版
典型写法:
<script
src="https://cdn.example.com/lib.js"
integrity="sha384-BASE64_HASH"
crossorigin="anonymous">
</script>
浏览器下载资源后计算哈希,与 integrity 中的值比对;一致才执行,不一致就阻止。跨源资源通常还要配合 crossorigin 和 CORS 响应头。SRI 不负责判断代码本身是否安全,只负责判断“这次加载的内容是否等于你预先信任的那份内容”。
完整版教学
一、SRI 解决什么风险
前端常从 CDN 加载库、监控脚本、支付 SDK 或样式文件。如果 CDN 被攻击、DNS 被劫持、构建链路被污染,用户浏览器可能下载到被替换的脚本。
页面 -> CDN lib.js
正常: lib.js hash = H1 -> 执行
被篡改: lib.js hash = H2 -> 与 integrity 不一致 -> 阻止
记忆钩子:SRI 像给外链资源贴封条,浏览器只执行封条匹配的那一份。
二、integrity 值是什么
integrity 由哈希算法和 Base64 哈希值组成,例如 sha384-...。构建或发布时先对目标文件内容计算摘要,HTML 中写入这个摘要,浏览器加载时重新计算。
openssl dgst -sha384 -binary lib.js | openssl base64 -A
如果文件改了 1 个字符,哈希值也会完全不同。假设原文件 100KB,攻击者只在末尾插入 20 字节窃取代码,浏览器计算出的摘要也无法匹配原 integrity。
三、为什么跨源常要 crossorigin
<link
rel="stylesheet"
href="https://cdn.example.com/app.css"
integrity="sha384-..."
crossorigin="anonymous">
浏览器对跨源资源有 CORS 和错误信息限制。使用 SRI 校验跨源资源时,通常需要资源服务器允许跨源读取,并在标签上设置合适的 crossorigin。否则浏览器可能因为无法进行完整校验而拒绝加载。
anonymous 表示不带凭证请求资源,适合公共 CDN。若资源需要携带凭证,要非常谨慎,因为第三方静态资源和用户凭证混在一起会扩大风险。
四、SRI 与 CSP 的配合
SRI 校验“文件内容是否匹配”,CSP 控制“哪些来源、哪些脚本类型允许执行”。二者组合更稳:CSP 限制脚本来源和内联脚本,SRI 防止允许来源上的文件被替换。
| 能力 | CSP | SRI |
|---|---|---|
| 限制加载来源 | 支持 | 不负责 |
| 阻止内联脚本 | 支持 | 不负责 |
| 校验外链内容 | 可配合 | 核心能力 |
| 防 CDN 文件篡改 | 间接 | 直接 |
如果只配置 CSP 允许 cdn.example.com,而 CDN 上的 lib.js 被替换,浏览器仍认为来源合法。SRI 可以补上这层内容校验。
五、版本更新和缓存边界
SRI 最大的工程成本是版本变化。只要资源内容变了,哈希就要同步更新;HTML 引用旧 hash 加载新文件,会导致资源加载失败。
lib@1.0.0.js -> sha384-A
lib@1.0.1.js -> sha384-B
HTML 仍写 sha384-A -> 浏览器拒绝 1.0.1
因此生产中更推荐引用带版本号或内容 hash 的不可变资源,例如 /lib.8f3a.js,并由构建系统自动注入 integrity。手写维护哈希很容易出错。
六、SRI 不能防什么
SRI 不能证明第三方库没有漏洞,也不能防止你主动升级到有问题的版本。它防的是“传输或托管过程中内容被替换”,不是“依赖选择错误”。
| 风险 | SRI 是否解决 |
|---|---|
| CDN 文件被篡改 | 能降低 |
| 依赖包本身有漏洞 | 不能 |
| 页面内联 XSS | 不能 |
| 资源版本升级后 hash 未更新 | 会阻止加载 |
所以它常和依赖审计、锁文件、CSP、第三方脚本治理一起出现,而不是单独作为完整供应链安全方案。
七、常见误区与追问
- 误区:用了 HTTPS 就不需要 SRI。 HTTPS 保护传输链路,但 CDN 源文件被替换时仍可能加载恶意内容。
- 误区:SRI 能保证库没有漏洞。 它只保证内容未被替换,不审计代码质量。
- 误区:资源更新不用改 integrity。 内容变化后哈希必须同步更新,否则浏览器会拒绝加载。
- 追问:为什么要配
crossorigin? 跨源 SRI 校验通常需要 CORS 参与,否则浏览器无法安全校验响应。 - 追问:SRI 适合所有资源吗? 更适合版本固定的外链脚本和样式,频繁变化资源维护成本高。
- 追问:SRI 和 CSP 谁更重要? 作用不同,CSP 管来源和执行策略,SRI 管内容完整性。
八、加强记忆
SRI 的核心是“哈希验货”:页面声明我只信这份文件的摘要,浏览器下载后重新算一次,匹配才执行。答题时围绕三个点展开最稳:外链资源可能被篡改,integrity + crossorigin 让浏览器校验内容,更新版本必须同步更新哈希。它是供应链防线的一环,不是依赖安全的全部。