前端资源完整性校验:Subresource Integrity 防篡改实战

发布时间:2026/10/31 15:35:53

前端资源完整性校验:Subresource Integrity 防篡改实战 前端资源完整性校验Subresource Integrity 防篡改实战一、CDN 上的 JS 文件被中间人篡改用户浑然不知执行了恶意代码CDN 劫持不是科幻场景。中间网络设备路由器、ISP 缓存在特定条件下可能篡改或替换静态资源。如果在页面中通过script srchttps://cdn.example.com/app.js引入脚本浏览器会无条件地下载并执行——它不关心文件是否被篡改。Subresource IntegritySRI是浏览器层面的防御机制在script或link标签上添加integrity属性指定目标资源的哈希值。浏览器下载资源后计算哈希并与integrity比对不匹配则拒绝加载。二、SRI 的工作机制sequenceDiagram participant Browser as 浏览器 participant HTML as HTML 文档 participant CDN as CDN participant Attacker as 攻击者 HTML-Browser: script integritysha384-xxx srccdn.com/app.js Browser-CDN: GET /app.js alt 正常路径 CDN--Browser: app.js (原始内容) Browser-Browser: 计算 SHA-384 哈希 Browser-Browser: 比对 integrity ✅ 匹配 Browser-Browser: 执行脚本 else 篡改路径 (中间人攻击) Attacker--Browser: app.js (被篡改内容) Browser-Browser: 计算 SHA-384 哈希 Browser-Browser: 比对 integrity ❌ 不匹配 Browser-Browser: 拒绝加载 Console 报错 end Note over Browser: SRI 检查是浏览器原生行为br/不依赖任何 JavaScript 代码SRI 的两个关键特性浏览器原生支持Chrome/Firefox/Safari/Edge 全部支持不需要任何 JavaScript 代码。哈希算法多样支持sha256、sha384、sha512。推荐sha384——足够安全且计算速度适中。三、生产级 SRI 集成方案构建时自动生成 integrity 哈希// webpack-sri-plugin.js // Webpack 插件构建时自动为生成的 JS/CSS 文件计算 SRI 哈希 const crypto require(crypto); const fs require(fs); const path require(path); class SRIWebpackPlugin { constructor(options {}) { this.options { algorithm: options.algorithm || sha384, // 排除不需要 SRI 的文件模式 exclude: options.exclude || [/\.html$/, /\.map$/], }; } apply(compiler) { compiler.hooks.afterEmit.tapAsync( SRIWebpackPlugin, (compilation, callback) { const assets compilation.assets; const sriManifest {}; // 遍历所有生成的资源 Object.keys(assets).forEach((filename) { // 检查是否需要排除 if (this.shouldExclude(filename)) return; const assetPath path.join( compilation.outputOptions.path, filename ); if (!fs.existsSync(assetPath)) return; // 读取文件内容并计算哈希 const content fs.readFileSync(assetPath); const hash crypto .createHash(this.options.algorithm) .update(content) .digest(base64); // SRI 格式: algorithm-base64hash const integrity ${this.options.algorithm}-${hash}; sriManifest[filename] { integrity, size: content.length, }; }); // 输出 SRI Manifest供模板引擎使用 const manifestPath path.join( compilation.outputOptions.path, sri-manifest.json ); fs.writeFileSync( manifestPath, JSON.stringify(sriManifest, null, 2) ); console.log( [SRI Plugin] 已为 ${Object.keys(sriManifest).length} 个资源生成 SRI 哈希 ); callback(); } ); } shouldExclude(filename) { return this.options.exclude.some((pattern) pattern.test(filename)); } } module.exports SRIWebpackPlugin;HTML 模板中自动注入 integrity// inject-sri.js // HTML 模板辅助函数根据 Manifest 自动注入 integrity 属性 const fs require(fs); const path require(path); class SRIInjector { constructor(manifestPath) { // 加载构建时生成的 SRI manifest this.manifest JSON.parse(fs.readFileSync(manifestPath, utf-8)); } /** * 为脚本资源生成带 integrity 的 script 标签 * param {string} src - 脚本 URL 路径 * param {Object} options - 额外属性 */ scriptTag(src, options {}) { const integrity this.getIntegrity(src); // 构建属性字符串 let attrs src${src}; if (integrity) { attrs integrity${integrity}; // crossoriginanonymous 必须在 integrity 存在时设置 // 否则浏览器不会执行 SRI 校验 attrs crossoriginanonymous; } if (options.async) attrs async; if (options.defer) attrs defer; return script ${attrs}/script; } /** * 为样式资源生成带 integrity 的 link 标签 */ linkTag(href, options {}) { const integrity this.getIntegrity(href); let attrs relstylesheet href${href}; if (integrity) { attrs integrity${integrity}; attrs crossoriginanonymous; } return link ${attrs}; } /** * 从 Manifest 中查找资源的 integrity 值 */ getIntegrity(resourceUrl) { // 提取文件名 const filename resourceUrl.split(/).pop().split(?)[0]; // 在 manifest 中查找匹配的文件 for (const [key, value] of Object.entries(this.manifest)) { if (key.endsWith(filename)) { return value.integrity; } } console.warn([SRI] 未找到资源 ${filename} 的 integrity 值); return null; } } module.exports SRIInjector;CSP 配合 SRI 的强化策略# nginx.conf 添加 Content-Security-Policy 头 add_header Content-Security-Policy default-src self; script-src self https://cdn.example.com require-sri-for sha384-abc123def456...; # 允许的内联脚本哈希 style-src self https://cdn.example.com require-sri-for; always;四、SRI 的局限和注意事项缺点文件更新时的同步问题每次构建文件哈希都变如果 CDN 上的文件和 HTML 中的 integrity 不同步先推送了 CDN 还是先发了 HTML用户会看到白屏。必须在部署流程中保证原子性。不支持动态脚本document.createElement(script)动态创建的脚本标签不支持 integrity。需要另外实现校验。Crossorigin 要求的陷阱如果 CDN 不返回Access-Control-Allow-Origin头浏览器即使下载成功也不会做 SRI 校验。禁用场景同源加载的资源src/app.jsCDN 劫持不适用SRI 无额外收益。资源 URL 动态拼接的场景无法预计算哈希。五、总结SRI 是防范 CDN 资源篡改的浏览器原生机制。集成流程构建时计算资源哈希生成 Manifest模板引擎根据 Manifest 自动注入integrity和crossorigin属性。必须注意三个工程细节资源部署和 HTML 部署的原子性避免哈希和文件不同步、CDN 需要支持 CORS 头、配置 CSP 的require-sri-for做兜底防护。
延伸阅读

更多相关文章

2026/10/31 15:34:26

DV-HOP节点定位精度优化:多通信半径与跳距加权

简介:面向无线传感器网络定位研究者的DV-Hop改进算法仿真材料,围绕多通信半径与跳距加权策略降低误差传播、提升节点定位精度,适合WSN课程设计、算法复现与参数对比等场景的高年级学生和开发人员参考。压缩包共5个文件,约66KB&…

2026/10/31 15:34:26

Calibre 3Dstack connect命令详解与IC验证实践

1. Calibre 3Dstack命令解析:connect功能深度剖析在IC验证领域,Calibre作为业界标准的物理验证工具,其3Dstack模块专门用于处理先进封装设计的复杂验证需求。今天我们要重点解析的是3Dstack模块中的connect命令——这个看似简单的指令在实际工…

2026/10/31 15:34:26

ponytail 轻量级任务编排与插件化扩展实战指南

1. 从“ponytail”这个标题说起:它到底是什么第一次看到“ponytail”这个词,很多人脑子里蹦出来的画面是扎在脑后的马尾辫。但在技术圈和工具链语境里,它早就不是发型那么简单了。我最早接触到这个词,是在一个前端工程化的讨论群里…

2026/10/31 15:34:26

ponytail 工具实战:轻量级信息聚合与快捷操作工作流搭建指南

1. 从“ponytail”这个标题说起:它到底是什么第一次看到“ponytail”这个词,很多人脑子里蹦出来的画面是扎起来的马尾辫。但在技术圈和效率工具圈里,ponytail 早就不是发型的意思了。它是一类轻量级信息聚合与快捷操作工具的代称,…

2026/10/31 15:34:26

Calibre 3Dstack工具链与connect命令在3D IC验证中的应用

1. Calibre 3Dstack工具链概述Calibre 3Dstack是Mentor Graphics(现为Siemens EDA)推出的针对3D IC设计的物理验证解决方案。作为Calibre工具家族的重要成员,它专门处理芯片堆叠设计中的复杂互连验证问题。在先进封装技术如HBM、Chiplet等架构…

2026/10/31 15:29:26

语音社交产品冷启动策略与内容增长引擎设计

1. 语音社交产品的冷启动困境与破局点2023年全球语音社交市场规模已达47.8亿美元,但新产品的90日留存率普遍低于15%。这个数据背后反映的是语音社交产品面临的典型增长困境:用户获取成本高、内容沉淀难、社交关系链脆弱。我在操盘多款语音社交产品时发现…

2026/10/30 20:55:10

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/30 20:55:10

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/30 20:55:09

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/31 0:02:41

猫狗目标检测数据集:VOC/COCO/YOLO三格式一体化实战包

简介:本资源是一套面向计算机视觉初学者与YOLO目标检测实践者的猫狗图像数据集及配套开发工具包,专为快速上手目标检测模型训练而设计。资源包含1000张真实场景高清猫狗图片,标注质量高,同时提供VOC(XML)、…

2026/10/31 0:02:41

HDU2017多校标程复现:算法竞赛工程化真题沙盒

简介:本资源为2017年HDU多校联合训练第一场官方配套资料,面向ACM程序设计竞赛备赛学生、算法爱好者及高校编程集训队成员,旨在提供权威解题参考与完整测试验证环境。压缩包共40个文件,含15份C标程(覆盖全部赛题&#x…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑