跳到主内容
快讯直播
AI智模界
AI 词典

SRI:一个 hash 怎么挡住被篡改的 CDN 脚本

一句话定义:SRI(Subresource Integrity,子资源完整性)是浏览器的一个校验机制——你在 HTML 里给外链脚本或样式表附上一串“内容指纹”,浏览器把文件下载下来后自己再算一遍,对不上就拒绝执行。

它是怎么工作的

```html

<script src="https://cdn.example.com/analytics.js"

integrity="sha384-加粗的一长串字符"

crossorigin="anonymous"></script>

```

浏览器做四件事:下载文件;按 SHA-384 计算文件内容的哈希值;把结果做 base64 编码;将这个结果与 integrity 属性的值逐字比对。完全一致才执行,不一致就静默丢弃,并在控制台报一条 integrity 错误。算法支持 SHA-256、SHA-384、SHA-512,也可以写多个哈希值并用空格分隔,只要任一匹配即可通过。

打个比方:这就像收货时核对封条号。你下单时就在自己的仓库里写下“这批货的封条号是 8f3a…”,货送到门口,你自己再核对一遍封条。中途有人调包,封条号对不上,你直接拒收。关键在于,约定这一步发生在你自己写的 HTML 里——攻击者能改 CDN 上的文件,却改不了你服务器发出的那份 HTML。攻击面被压缩到“HTML 和 hash 字符串本身”。

为什么偏偏只对 script 和 link 有效

从规范看,integrity 属性只定义在 <script> 和 <link>(如 rel="stylesheet")上,其他元素写了也不生效。从设计看也有道理:

  • 这两类资源是会被执行、或能整体改变页面外观的高危资源,一旦被换掉,等同于页面被接管。
  • 它们本来就是整份下载完才生效的,浏览器在“应用”之前天然有一个拦截点,先校验再执行几乎不增加额外代价。
  • 图片、iframe 等是流式加载、渐进渲染的,把整份内容攒齐再校验会破坏边下边显示的体验,而且风险模型不同(图片不会执行代码)。<img> 上的完整性校验有提案,但浏览器支持很有限,实际能不能用以官方文档为准。

另外提醒一个最常见的踩坑:跨域资源必须带 CORS 头,即上面那个 crossorigin="anonymous",服务端要回 Access-Control-Allow-Origin。否则浏览器拿不到可用于校验的响应内容,结果是资源直接不加载——不是“不校验”,是“不执行”。

和相邻概念的区别

机制保护什么粒度拦不住什么
SRI单个外链文件的字节内容文件级内容指纹HTML 自身被篡改、内联脚本
HTTPS传输链路通道CDN 源站被入侵、第三方脚本自己作恶
CSP允许从哪些来源加载或执行来源白名单 + 内联脚本哈希白名单来源内的文件被替换

三者是叠加关系,不是替代关系。CSP 里的 script-src 'sha384-...' 是给内联脚本用的白名单,SRI 管的是外链文件,两者常被混淆。

对从业者的实际意义

它的主战场是供应链攻击:第三方统计、客服 SDK、UI 库、模型演示页里引的 CDN 脚本,只要 CDN 被入侵、DNS 被劫持、或者上游包被投毒后推到了 CDN,页面就会在毫无察觉的情况下执行别人的代码。SRI 让“内容变了”这件事变成一个可见的失败。

代价也很实在:资源一更新,integrity 就得跟着更新,通常交给构建工具自动生成(也可以用 openssl dgst -sha384 -binary 配合 base64 手工算)。而且版本频繁漂移的第三方脚本不适合加 SRI——对方一改文件你的页面就挂,这类脚本应改为引用固定版本 URL,并跟供应商确认。同理,SRI 保护不了被篡改的 HTML 本身,它只是纵深防御里的一层低成本保险。

AI 生成本文由 AI 基于公开信息自动生成,仅供参考。