子资源完整性(Subresource Integrity,SRI)安全机制与防护
字数 1396 2025-11-22 23:44:26
子资源完整性(Subresource Integrity,SRI)安全机制与防护
1. 知识点描述
子资源完整性(SRI)是一种安全特性,用于验证通过CDN或其他外部源加载的资源(如JavaScript库、CSS文件)是否被篡改。其核心原理是通过在引用资源时附加加密哈希值,浏览器会对比资源的实际哈希值与预期值,若不匹配则拒绝加载,从而防御供应链攻击或CDN劫持。
2. 为什么需要SRI?
- 风险场景:
- 开发者常用公共CDN(如unpkg、cdnjs)加速第三方库(如jQuery、Vue.js)的加载。
- 若攻击者入侵CDN或发起中间人攻击,可能注入后门代码到资源中。
- 即使使用自家CDN,若未启用HTTPS或配置不当,仍可能被劫持。
- 典型案例:
2017年,Mac版CCleaner软件被植入恶意代码,因攻击者篡改了其编译环境的依赖库。
3. SRI的实现原理
步骤1:生成资源哈希值
使用加密哈希算法(如SHA-384)计算资源的摘要值。例如,通过OpenSSL生成:
openssl dgst -sha384 -binary jquery.js | openssl base64 -A
或在线工具(仅限测试环境)计算文件哈希。
步骤2:在HTML中附加完整性校验
通过<script>或<link>标签的integrity属性指定哈希值,格式为:算法-摘要值。
<script
src="https://cdn.example.com/jquery.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R8GqX8g/6Qttt8Et12aGM3fK2B4b7gQsFw2Il4a"
crossorigin="anonymous">
</script>
crossorigin="anonymous":确保CORS策略允许跨域资源校验。
步骤3:浏览器验证流程
- 下载资源文件。
- 使用
integrity指定的算法(如SHA-384)计算资源哈希。 - 对比计算结果与
integrity中的哈希值:- 匹配则加载资源。
- 不匹配则阻断加载并报错(浏览器控制台可见错误日志)。
4. 进阶细节与注意事项
(1)哈希算法选择
- 推荐使用
SHA-384(平衡安全与性能),避免弱算法(如SHA-1)。 - 支持多哈希备选:
integrity="sha256-... sha384-...",浏览器按顺序尝试第一个支持的算法。
(2)动态资源的挑战
- 若资源内容动态变化(如A/B测试版本),需同步更新哈希值,否则会触发阻断。
- 解决方案:
- 静态资源严格使用SRI。
- 动态资源通过其他机制(如签名、WAF)防护。
(3)与缓存机制的交互
- 哈希校验失败时,浏览器可能缓存失败结果,需强制刷新或清除缓存。
(4)自动化集成
- 在CI/CD流水线中通过工具(如Webpack的
webpack-subresource-integrity插件)自动生成并注入哈希值。
5. 防护效果与局限性
- 优势:
- 有效防御CDN劫持、MITM攻击、恶意第三方资源注入。
- 支持所有现代浏览器,向后兼容(不支持的浏览器会忽略
integrity)。
- 局限:
- 无法防御首次上传即被篡改的资源(依赖初始哈希值的正确性)。
- 需确保哈希值传输过程安全(如通过HTTPS页面分发)。
6. 实战配置示例
以Vue.js资源为例:
- 获取官方CDN资源URL:
https://unpkg.com/vue@3/dist/vue.global.js - 生成SHA-384哈希:
curl -s https://unpkg.com/vue@3/dist/vue.global.js | openssl dgst -sha384 -binary | openssl base64 -A - 注入HTML:
<script src="https://unpkg.com/vue@3/dist/vue.global.js" integrity="sha384-示例哈希值(实际需替换)" crossorigin="anonymous"> </script>
7. 扩展:SRI与CSP的协同防护
- 结合内容安全策略(CSP)的
require-sri-for指令,强制关键资源启用SRI:Content-Security-Policy: require-sri-for script style; - 多层防御:SRI校验资源完整性 + CSP限制资源加载源 + HTTPS保证传输安全。