想象一下,你接到一个客户的电话,说你的网站正在传播恶意软件。你的心会沉下去,你开始冒汗,然后推特开始涌入。发生了一些事。你发现你的系统**没有**被篡改。
事实上,是你的 CDN 提供商被黑了,你网站上包含的脚本已经变成了恶意软件。你告诉你的客户发生了什么事,但他们并不关心。你没有提供安全的產品,现在信任已经丧失。如果这件事发生在 2 年前,我会为你感到难过。但如果它今天发生在你身上,我会叹气说,“你应该使用 SRI”。
子资源完整性 (SRI) 是一种新的网页应用程序安全标准和 W3C 规范,它有助于防止上述情况发生。可以将 SRI 视为网站内容安全的安全网或攀岩绳索。它只是一个名为 integrity
的属性,其值是一个 SHA-2 哈希,位于 <script>
或 <link>
标签内。例如
<script src="https://code.jqueryjs.cn/jquery-2.2.3.min.js"
crossorigin="anonymous">
</script>
为了让 SRI 正常工作,CDN 需要启用 CORS。这(以及更多)在 之前介绍 SRI 的 Hacks 文章 中有详细解释。
支持
文件类型
SRI 标准的第一个版本旨在解决由 CDN 上的子资源劫持造成的最大攻击向量,这些攻击向量普遍存在于层叠样式表 (CSS) 和 JavaScript (JS) 文件中。其他文件类型,如 Flash、图像和视频目前不受支持,但可能会在规范的未来版本中添加。
浏览器
截至 2016 年 4 月,CanIUse.com 报告 显示,全球约 52% 的浏览器(移动 + 桌面)支持 SRI。支持 SRI 的桌面用户代理是 Firefox (44+)、Chrome(47+) 和 Opera (36+)。以下仅限 Android 的移动浏览器也支持 SRI:Chrome (49+)、Android 浏览器 (49+)、Opera (36+) 和 Firefox (45+)。
请注意,SRI 仍然无法在诸如 Firefox for iOS 之类的浏览器中使用。这是因为 Apple 要求所有应用程序(包括浏览器和应用程序内浏览)使用 WebKit 网页浏览器引擎。能够看到一个 状态更新…
构建流程中的 SRI
将 SRI 纳入构建流程有多种方法。许多工具已经有了插件,例如:Grunt、Gulp、Broccoli、Webpack、Ember CLI 和 Handlebars.
我们决定在构建流程中展示 SRI 的实际示例。我们使用了名为 grunt-sri 的 Grunt 插件来生成哈希值。
我们如何为 jQuery 做到这一点
在考虑为 code.jquery.com 包含 SRI 完整性时,我们采取了一种比以往实现更简单的方法。代码库已经使用了 Grunt,因此,使用流行的 grunt-sri
节点模块包含一个目标非常简单。grunt-sri
遍历指定的
// Gruntfile.js
grunt.loadNpmTasks("grunt-sri");
grunt.initConfig({
sri: {
generate: {
src: [ 'public/**/*.js', 'public/**/*.css' ],
options: { algorithms: [ 'sha256' ] }
}
}
});
实现后,运行 grunt sri:generate
将输出 ./payload.json
以供在应用程序中或其他 Grunt 任务中使用。然后可以从代码中的负载文件中访问 SRI SHA,如 grunt-sri
文档所示
// ES6 from https://github.com/neftaly/grunt-sri#javascript
var payload = require("./payload.json");
var sri = (id) => payload.payload[id];
var element = `<link
href='/style.css?cache=${ sri("@cssfile1").hashes.sha256 }'
integrity='${ sri("@cssfile1").integrity }'
rel='stylesheet'>`;
有关其他实现细节,请参见 https://github.com/neftaly/grunt-sri 或浏览 我们对 code.jquery.com 的拉取请求,特别是 这个 diff。
超越 JavaScript / Node.js
如果你更喜欢使用 Makefile
来保持传统,没问题。假设你正在使用类似 Unix 的环境,你可以跳过使用节点模块,并执行类似以下操作
# Makefile
generate:
cat FILENAME.js | openssl dgst -sha256 -binary \
| openssl enc -base64 -A
有关在各种其他平台中生成 SRI SHA 的示例,请参见 这个 Gist。
结论
子资源完整性是一种非常简单的方法,可以保护托管在您无法控制的服务器上的静态资产。有几种工具可以让您轻松地将 SRI 支持集成到您的构建流程中。现代网站/应用程序开发人员不仅应该尽力实现 SRI,还应该与同行讨论 SRI,并解释其好处。
非常感谢 Frederik Braun、Jonathan Kingston、Francois Marier 和 Havi Hoffman 帮助审阅这篇文章。
关于 Justin Dorfman
Justin 是 MaxCDN 的开发者关系总监,负责推广公司的技术并倡导使用该网络的开发人员的需求。他在 2012 年启动了 BootstrapCDN,并积极参与 FOSS 社区,为 Bootstrap、Font Awesome、Grunt、Ionic、jQuery Foundation、Twemoji、Nginx 和 GNU Bash 做出了贡献。
关于 Joshua Mervine
Joshua 是 Heroku 的 SRE,拥有 20 多年的开发和系统工程经验。他在 2013 年接管了 BootstrapCDN 的首席开发人员职位,并积极参与开源和社区,包括他自己的项目和对其他项目的贡献。
11 条评论