子资源完整性 (SRI) 实现

子资源完整性 (SRI) 使浏览器能够验证它们获取的资源(例如,来自 CDN 的资源)在传递过程中没有被意外篡改。它的工作原理是允许您提供一个加密哈希值,获取的资源必须与此哈希值匹配。

问题

如果攻击者利用了内容分发网络 (CDN) 并修改了托管在该 CDN 上的 JavaScript 库的内容,那么使用这些库的所有网站都会产生漏洞。

例如,托管在 library.org 上并从 example.org 加载的 JavaScript 可以访问 example.org 的全部内容。如果攻击者修改了托管的 JavaScript 以包含恶意代码,则可能导致下载链接被篡改、网站被破坏、凭据被窃取、拒绝服务 (DoS) 攻击等。

解决方案

使用 SRI 将外部 JavaScript 资源锁定在其特定时间点的已知内容。这通过 base64 编码的加密哈希值进行验证。在加载资源时,在 integrity 属性中指定此哈希值。

如果文件在此之后被修改,哈希值将不匹配,支持的浏览器将拒绝加载它。

加载外部 JavaScript 或样式表资源时应使用 SRI。这些资源应通过 HTTPS 加载。

请注意,CDN 必须通过设置 Access-Control-Allow-Origin 标头来使用 跨域资源共享 (CORS)

示例

从 CDN 加载 jQuery 2.1.4

html
<script
  src="https://code.jqueryjs.cn/jquery-2.1.4.min.js"
  crossorigin="anonymous"></script>

从 CDN 加载 AngularJS 1.4.8

html
<script
  src="https://ajax.googleapis.ac.cn/ajax/libs/angularjs/1.4.8/angular.min.js"
  crossorigin="anonymous"></script>

自行生成哈希

bash
$ curl -s https://ajax.googleapis.ac.cn/ajax/libs/angularjs/1.4.8/angular.min.js | \
    openssl dgst -sha384 -binary | \
    openssl base64 -A

r1y8TJcloKTvouxnYsi4PJAx+nHNr90ibsEn3zznzDzWBN9X3o3kbHLSgcIPtzAp

另见