关于 Subresource Integrity

2019-02-01 1815点热度 0人点赞

偶然间在 Bootstrap 官网翻链接时发现了他们的链接使用了一个新参数 Integrity 于是查了一下相关资料


1 、 SRI 介绍

SRI 是 Subresource Integrity 的缩写,翻译为:子资源完整性,旨在提供一种保护网站交付的方法 [ 链接 ]

SRI 主要用于保证没有中间人在客户端传输期间对网页元素文件进行任何篡改(中间人可能来自 CDN 劫持或者其他任何地方)

为了使用 SRI,希望包括来自第三方的资源的网站作者除了资源的位置之外还可以指定资源的加密散列。然后,获取资源的浏览器可以将网站作者提供的散列与从资源计算的散列进行比较。如果散列不匹配,则丢弃资源。

比如下面这个 HTML 代码,它限制了 "当 anonymous 用户请求 bootstrap.min.css 时,此文件的 sha384 校验为
JzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">

2 、使用方法

首先我们对一个文件进行校验

cat file.css | openssl dgst -sha384 -binary | openssl base64 -A

当然你也可以用 sha 命令组进行校验

sha384sum -b file.css | awk '{ print $1 }' | xxd -r -p | base64

校验完毕后你获得一串代码,比如 hello 的校验可以得到

WeF0h3dEjGnea4ANejO7+5/xtGPkQ1TDVTvNucZm+pASWjx5+QOXvfX2oT3oKGhP

此时你需要在这串代码前面添加一个校验类型头部,由于刚才我们使用的是 sha384 所以我们整合后的内容为

sha384-WeF0h3dEjGnea4ANejO7+5/xtGPkQ1TDVTvNucZm+pASWjx5+QOXvfX2oT3oKGhP

完毕后我们在这串内容添加到 html 的对应文件中即可

<link rel="stylesheet" href="https://example.com/file.css" integrity="sha384-WeF0h3dEjGnea4ANejO7+5/xtGPkQ1TDVTvNucZm+pASWjx5+QOXvfX2oT3oKGhP">

注意:SRI 一共支持 sha256 sha384 sha512 三种检查代码,你可以根据需要生成不同的校验代码。

当所有的 SRI 配置均已添加后,可以强制要求浏览器对某类别校验 SRI 并丢弃 错误 SRI 和 无 SRI 内容。
下例为针对所有 javascript 进行管制

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

3 、其他问题

当你的 CDN 或者用户运营商网络向 css/js 文件中插入一些代码时,网页将停止加载(比如中国移动家庭宽带插入的移动话费提醒)

然而在 HTTP 使用时经常出现的被劫持问题,HTTPS 后已经非常少见了。所以现在也只是图个安静。

但是此方法仍然不能保证 html 文件的被篡改可能,毕竟校验的只是网页元素。


4 、参考文章

How Subresource Integrity helps [ 链接 ]

StarryVoid

Have a good time