这篇翻译不完整。请帮忙从英语翻译这篇文章

子资源完整性(SRI)是允许浏览器检查其获得的资源(例如从 CDN 获得的)是否被篡改的一项安全特性。它通过验证获取文件的哈希值是否和你提供的哈希值一样来判断资源是否被篡改。

SRI 如何工作

使用 内容分发网络 (CDNs) 在多个站点之间共享脚本和样式表等文件可以提高站点性能并节省带宽。然而,使用CDN也存在风险,如果攻击者获得对 CDN 的控制权,则可以将任意恶意内容注入到 CDN 上的文件中 (或完全替换掉文件)
),因此可能潜在地攻击所有从该 CDN 获取文件的站点。

子资源完整性通过确保 Web 应用程序获得的文件未经第三方注入或其他任何形式的修改来降低这种攻击的风险。

如何使用 SRI

将使用 base64 编码过后的文件哈希值写入你所引用的 <script> 或 <link> 标签的 integrigy 属性值中即可启用子资源完整性功能。

integrity 值分成两个部分,第一部分指定哈希值的生成算法(目前支持 sha256、sha384 及 sha512),第二部分是经过 base64 编码的实际哈希值,两者之间通过一个短横(-)分割。

integrity 值可以包含多个由空格分隔的哈希值,只要文件匹配其中任意一个哈希值,就可以通过校验并加载该资源。

使用 base64 编码 sha384 算法计算出摘要后的 integrity 值的例子:

sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC

integrity 中的“hash”部分,严格来说,是一种经过特定的哈希函数转换之后的密码学摘要。但是更一般的叫法就是哈希,本文用的也是这种叫法。

生成 SRI 哈希的工具

你可以用 openssl 在命令行中执行如下命令来生成 SRI 哈希值:

cat FILENAME.js | openssl dgst -sha384 -binary | openssl enc -base64 -A         

或者用 shasum 在命令行中执行:

shasum -b -a 384 FILENAME.js | xxd -r -p | base64

另外,SRI Hash Generator 是一个在线生成 SRI 哈希值的工具。

内容安全策略及子资源完整性

你可以根据内容安全策略来配置你的服务器使得指定类型的文件遵守 SRI。这是通过在 CSP 头部添加 require-sri-for 指令实现的:

Content-Security-Policy: require-sri-for script;

这条指令规定了所有 JavaScript 都要有 integrity 属性,且通过验证才能被加载。

你也可以指定所有样式表也要通过 SRI 验证:

Content-Security-Policy: require-sri-for style;

你也可以对两者都加上验证。

范例

在这个例子中,我们已知 oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC 是一个指定文件,比如 example-framework.js,经过 SHA-384 算法得出的摘要,同时在 https://example.com/example-framework.js 上有其一份拷贝。

在 script 标签中增加 SRI

你可以使用以下的 <script> 元素告诉浏览器在执行 https://example.com/example-framework.js 中的内容之前,必须先比较该文件的哈希值是否和预期的一致,只有一致才能执行。

<script src="https://example.com/example-framework.js"
        integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
        crossorigin="anonymous"></script>

有关 crossorigin 属性的更多信息,见 CORS settings attributes.

浏览器如何处理 SRI

浏览器根据以下步骤处理 SRI:

  1. 当浏览器在  <script> 或者 <link>  标签中遇到 integrity 属性之后,会在执行脚本或者应用样式表之前对比所加载文件的哈希值和期望的哈希值。
  2. 当脚本或者样式表的哈希值和期望的不一致时,浏览器必须拒绝执行脚本或者应用样式表,并且必须返回一个网络错误说明获得脚本或样式表失败。

规范

规范 状态 注释
Subresource Integrity Recommendation  
Fetch Living Standard  

浏览器兼容性

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
The integrity attribute for <script> and <link> 45.0 43 (43) 未实现 32 未实现 [1]
The CSP require-sri-for directive ? 49 (49) ? ? ?
Feature Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
The integrity attribute for <script> and <link> 45.0 43.0 (43) 未实现 未实现 未实现 [1]
The CSP require-sri-for directive ? 49.0 (49) ? ? ?

[1] WebKit bug 148363

[2] 位于 security.csp.experimentalEnabled 之后的是: config preference。

相关资料

文档标签和贡献者

此页面的贡献者: kingcc, Roland_Reed, xgqfrms-GitHub
最后编辑者: kingcc,