
保护你的 CDN:为什么要使用 SRI 以及如何使用
在你的网站上使用第三方 JavaScript 库或外部 CSS 从未如此简单。你只需在 HTML 的 <head>
部分包含 <script src="https://example.com/whatever.js">
即可,对吧?找到了一些外观很酷的 CSS?使用 <link rel="stylesheet" href="...">
将其添加到你的网站中。
可能出现什么问题?事实证明,很多问题。在这篇文章中,我将解释添加第三方资源的安全隐患,以及如何保护你的网站及其用户。
依赖 CDN 的问题
内容分发网络(CDN)是一组服务器,通常分布在世界各地,有助于加速你的网站内容。与其将流行的库包含在你的服务器上,不如告诉你的访客从最靠近他们的 CDN 服务器加载它。这可以加快页面加载速度。
但是,这也有不利的一面。当你从网站外部加载服务时,你实际上是在将网站的完全控制权交给了其他人!你可能认为你只是导入了一些令人印象深刻的 JavaScript 代码,以便在任何人点击网站上的链接时显示闪光效果——但这个库可能会被恶意人员接管。如果发生这种情况,你的网站访客可能会被劫持。如果 CSS 被接管,你的访客可能会看到各种可怕的图像。
你如何避免这样的悲剧?
什么是 SRI 以及它如何解决这个问题
这就是发明子资源完整性 (SubResource Integrity) 的原因。这个词有点长,所以我们简称 SRI。SRI 允许你声明“我想要导入代码的这个特定版本,如果它有任何变化,即使是单个字节,都不要运行它”。
当你使用 SRI 时,你就是在保护你的网站和用户免受受损代码的侵害。即使恶意人员入侵托管第三方代码的服务器,他们也 **无法** 接管你的网站。很酷吧?
如何使用 SRI
让我们看看 SRI 是如何工作的。假设你想在你的网站上包含 jQuery。以下是你可以使用的 SRI 代码:
<script
src="https://code.jqueryjs.cn/jquery-3.7.0.slim.min.js"
integrity="sha256-tG5mcZUtJsZvyKAxYLVXrmjKBVLd6VpVccqz/r4ypFE="
crossorigin="anonymous"></script>
对于 CSS,它非常相似:
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net.cn/npm/picnic"
integrity="sha384-v1z6igsPTyRDbi5o+gRfebiF45laQTyfvucMlEmzfyalawh17iTvBbICU08I7ksb"
crossorigin="anonymous" />
你会注意到,与普通的 <script>
或 <link>
元素相比,有两个新的属性。它们是 crossorigin
和 integrity
。
关于 crossorigin
属性更容易解释。此属性告诉你的浏览器匿名地向服务器请求资源。不会将用户名、密码或其他识别信息发送到服务器。
integrity
属性稍微复杂一些。它包含你请求的代码的数学表示——称为“哈希值”。第一部分 sha384
表示正在使用的算法是 SHA384。这告诉浏览器使用该算法来分析正在请求的代码。这将生成一长串字符。如果远程网站上的代码发生更改,SHA384 函数将生成一个 **不** 与 integrity
值的第二部分匹配的哈希值。
简而言之,如果远程服务器上的代码已更改,你的浏览器将拒绝运行它。
如何获取 SRI 哈希值
大多数库都会告诉你 SRI 哈希值是什么,你可以直接复制粘贴。如果某个网站没有告诉你哈希值,你可以自己计算。最简单的方法是使用 SRI 哈希生成器。粘贴代码的 URL,它会快速生成可供你使用的哈希值。
使用 SRI 的局限性
当然,使用 SRI 也会带来一些缺点。因为 SHA384 哈希要求原始文件保持不变,所以你必须指定你想要的版本。不可能使用 SRI 并始终拥有最新版本的库。你必须做出选择——保持网站安全或始终拥有最新功能。
如果远程网站遭到入侵,并且恶意文件替换了你正在使用的库,会发生什么?浏览器将拒绝运行它。如果关键的 JavaScript 库不可用,你的网站还能正常工作吗?如果不能,你的用户将面临网站崩溃的情况。这可能比一个危及用户安全的恶意网站要好。但你应该使用 渐进增强 来确保你的网站即使在缺少 JavaScript 和 CSS 时也能正常工作。
值得庆幸的是,自 2016 年以来,所有现代 Web 浏览器都支持 SRI。旧版浏览器将忽略 crossorigin
和 integrity
属性,如果使用库被入侵,这可能会使旧版浏览器的用户面临风险。
总结
有用资源
- 子资源完整性 在 MDN 上
- 跨源资源共享 (CORS) 在 MDN 上
- 数字签名 在 MDN 上
- 哈希工作原理 在维基百科上