发布时间:2026/7/15 21:53:10
前端资源完整性校验: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/7/15 22:58:21

数据科学职业地基:统计思维、Python表达与业务落地三本书

1. 这三本书,我带了六届数据科学新人一起读,不是“入门清单”,而是职业地基的三块压舱石刚带完今年第三期数据科学实习项目,有个实习生在结业复盘时问我:“老师,您总说别急着学代码、别急着调参&#xff0c…

2026/7/15 22:58:21

2026龙虾AI企业搭建推荐 AionClaw 等五款智能体场景化选型参考

前言 数字化转型背景下,龙虾 AI 智能体可自主完成电脑端操作、支持长时段自动化运行、多智能体协同处理办公任务,成为各类规模企业搭建数字员工体系的常用工具。2026 年市场内各类龙虾 AI 智能体在底层架构、部署方式、行业适配方向上存在明显区分&#…

2026/7/15 22:58:21

龙虾企业 AI 智能体哪家好?AionClaw本地私有化龙虾智能体全面评测

当下数字化转型浪潮中,不少企业管理者都在咨询龙虾企业 AI 智能体哪家好。市面上畅龙虾、腾讯 QClaw、开源 OpenClaw 等多款龙虾类智能体层出不穷,但普遍存在云端数据泄露、部署复杂、功能单一、无法长期自主运行等痛点。AionClaw 作为 OpenClaw 开源项目…

2026/7/15 22:53:21

鸿蒙 ArkTS 实战:EV Charging Spots 从出行记录到状态反馈完整解析

鸿蒙 ArkTS 实战:EV Charging Spots 从出行记录到状态反馈完整解析 前言 EV Charging Spots 是一个面向 出行管理与通勤习惯 的鸿蒙 ArkTS 小应用。记录出行条目、站点信息和提醒备注,适合日常出行复盘。 本文基于 entry/src/main/ets/pages/Index.ets…

2026/7/15 17:04:06

3步解锁音乐自由:ncmdumpGUI终极NCM文件解密转换指南

3步解锁音乐自由:ncmdumpGUI终极NCM文件解密转换指南 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾在网易云音乐下载了心爱的歌曲&#…

2026/7/15 22:21:34

CANoe 19 SP3 配置 GB/T 27930-2023 A类系统:3步搭建BMS仿真测试环境

CANoe 19 SP3 配置 GB/T 27930-2023 A类系统:3步搭建BMS仿真测试环境随着新能源汽车行业的快速发展,充电通信协议的标准化和测试验证变得尤为重要。GB/T 27930-2023作为中国智能充电协议的最新版本,对充电机与电动汽车之间的通信提出了更严格…

2026/7/14 18:30:06

3步搞定RTL8852BE驱动:从零开始配置Wi-Fi 6网卡

3步搞定RTL8852BE驱动:从零开始配置Wi-Fi 6网卡 【免费下载链接】rtl8852be Realtek Linux WLAN Driver for RTL8852BE 项目地址: https://gitcode.com/gh_mirrors/rt/rtl8852be 还在为Linux系统无法识别RTL8852BE Wi-Fi 6网卡而烦恼吗?&#x1f…

2026/7/15 0:08:29

【LINUX】驱动

【LINUX驱动】【字符设备】【中断】【Platform】【网课 设备树】【GPIO】【PINCTRL】【INPUT】【IIC】【SPI】【网络驱动】【屏幕驱动】【一 设备树】【二 内核模块编译】【三 基本驱动框架】【四 Platform总线设备驱动框架】【五 驱动子系统】【六 综合】

2026/7/15 0:08:29

【1982-2026】全国高精度建筑轮廓|村级精度|SHP矢量

🔍 数据简介 本次分享1982-2026年全国村级精度建筑轮廓矢量数据,覆盖全国各省市区县,到村级别精细,为2026年最新实时采集成果,非网传仅60/77个城市的老旧数据。 数据含带高度/不带高度双版本,单体建筑边界精…

2026/7/15 0:08:29

【1975-2026】全国水系水路数据|河流/水库/运河|SHP矢量

🔍 数据简介 本次分享1975-2026年全国高精度水系水路矢量数据,覆盖全国全域,包含河流、水系、水库、运河、湿地、冰川、沟渠等全类别水文要素。 数据集包含双层矢量图层,字段分类清晰、要素齐全,支持2013-2026逐年完整…

2026/7/15 13:36:32

3个高效策略:快速掌握Axure中文界面配置

3个高效策略:快速掌握Axure中文界面配置 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面感…