子资源完整性 (SRI) 实现

子资源完整性 (SRI) 使浏览器能够验证他们获取的资源(例如,来自 CDN)是否在没有意外操纵的情况下交付。它通过允许您提供一个加密哈希来工作,该哈希必须与获取的资源匹配。

问题

如果攻击者利用内容交付网络 (CDN) 并修改了托管在该 CDN 上的 JavaScript 库的内容,它将在使用这些库的所有网站中创建漏洞。

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

解决方案

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

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

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

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

示例

从其 CDN 加载 jQuery 2.1.4

html
<script
  src="https://code.jquery.com/jquery-2.1.4.min.js"
  integrity="sha384-R4/ztc4ZlRqWjqIuvf6RX5yb/v90qNGx6fS48N0tRxiGkqveZETq72KgDVJCp2TC"
  crossorigin="anonymous"></script>

从其 CDN 加载 AngularJS 1.4.8

html
<script
  src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"
  integrity="sha384-r1y8TJcloKTvouxnYsi4PJAx+nHNr90ibsEn3zznzDzWBN9X3o3kbHLSgcIPtzAp"
  crossorigin="anonymous"></script>

自己生成哈希

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

r1y8TJcloKTvouxnYsi4PJAx+nHNr90ibsEn3zznzDzWBN9X3o3kbHLSgcIPtzAp

另请参见