JavaScript内核与高级编程之：`JavaScript`的`Subresource Integrity`：其在 `CDN` 安全中的应用。

admin
Tue, 26 Aug 2025 12:08:03 +0000
Javascript, integrity, javascript, subresource

各位观众老爷们，早上好/下午好/晚上好！ 咱们今天啊，聊点刺激的，讲讲“城门失火，殃及池鱼”的JS安全问题，以及如何用Subresource Integrity (SRI) 这把“安全锁”来保护咱们的网站。 Part 1: JS，你的甜蜜负担？ 想象一下，你开了一家豪华餐厅（你的网站），为了让客人（用户）体验更好，你从最好的供应商（CDN）那里订购了精美的餐具（JS库，比如jQuery、Bootstrap）。 这些餐具确实让你的餐厅蓬荜生辉，但问题来了：如果供应商的仓库（CDN服务器）被黑了，或者内部员工做了手脚，餐具上被人下了毒（恶意代码），那你的客人岂不是要遭殃？ 这就是JS的甜蜜负担。 我们为了快速开发和提升用户体验，大量使用第三方CDN提供的JS库。 但这些库一旦被篡改，轻则影响网站功能，重则窃取用户数据，甚至直接植入恶意代码，让用户变成肉鸡。 这段代码看起来很 …

继续阅读“JavaScript内核与高级编程之：`JavaScript`的`Subresource Integrity`：其在 `CDN` 安全中的应用。”

The post JavaScript内核与高级编程之：`JavaScript`的`Subresource Integrity`：其在 `CDN` 安全中的应用。 first appeared on 智猿学院-前后端，数据库，人工智能，云计算等领域前沿技术讲座.

各位观众老爷们，早上好/下午好/晚上好！ 咱们今天啊，聊点刺激的，讲讲“城门失火，殃及池鱼”的JS安全问题，以及如何用Subresource Integrity (SRI) 这把“安全锁”来保护咱们的网站。

Part 1: JS，你的甜蜜负担？

想象一下，你开了一家豪华餐厅（你的网站），为了让客人（用户）体验更好，你从最好的供应商（CDN）那里订购了精美的餐具（JS库，比如jQuery、Bootstrap）。 这些餐具确实让你的餐厅蓬荜生辉，但问题来了：如果供应商的仓库（CDN服务器）被黑了，或者内部员工做了手脚，餐具上被人下了毒（恶意代码），那你的客人岂不是要遭殃？

这就是JS的甜蜜负担。 我们为了快速开发和提升用户体验，大量使用第三方CDN提供的JS库。 但这些库一旦被篡改，轻则影响网站功能，重则窃取用户数据，甚至直接植入恶意代码，让用户变成肉鸡。




这段代码看起来很普通，但它也存在潜在的风险。 如果cdn.example.com被攻破，或者jquery.min.js被恶意替换，你的网站就岌岌可危了。

Part 2: SRI：给你的CDN资源上把锁

Subresource Integrity (SRI) 就像给你的CDN资源上了一把“安全锁”。 它通过校验资源的哈希值，确保浏览器加载的资源与你预期的完全一致，防止被篡改。

简单来说，SRI的工作原理是这样的：

1. 生成哈希值： 在你部署网站之前，先对你使用的CDN资源（比如jQuery、Bootstrap的JS文件）生成一个唯一的哈希值（你可以理解为文件的指纹）。

2. 添加integrity属性： 将这个哈希值添加到 或 标签的 integrity 属性中。

3. 浏览器校验： 当浏览器加载资源时，会根据 integrity 属性中的哈希值，对下载的资源进行校验。 如果哈希值不匹配，浏览器会拒绝执行该资源，从而防止恶意代码的执行。

Part 3: SRI的“锁”怎么上？ (代码示例)

咱们来点实际的，看看如何给CDN资源上锁。

1. 生成哈希值：

你可以使用各种工具来生成哈希值，比如OpenSSL、在线哈希生成器等等。 这里我们用OpenSSL来演示：

# 以 sha384 为例，生成 jquery.min.js 的哈希值
openssl dgst -sha384 jquery.min.js -binary | openssl base64 -A

执行完上面的命令，你会得到类似这样的哈希值：

sha384-vk6g625u2wvWjWqJt548fa19v4kE5/qii6YvLzL11m/yvL42/qgB8/x186s911Q

注意： 不同的哈希算法生成的哈希值是不同的。 常用的哈希算法有 sha256、sha384 和 sha512。 一般来说，sha384 是一个不错的选择，因为它在安全性和性能之间取得了平衡。 sha512 更安全，但计算量更大，可能会影响性能。

2. 添加integrity属性：

拿到哈希值后，就可以把它添加到 标签的 integrity 属性中。 同时，你还需要指定使用的哈希算法。

<script
  src="https://cdn.example.com/jquery.min.js"
  integrity="sha384-vk6g625u2wvWjWqJt548fa19v4kE5/qii6YvLzL11m/yvL42/qgB8/x186s911Q"
  crossorigin="anonymous"
>

integrity="sha384-vk6g625u2wvWjWqJt548fa19v4kE5/qii6YvLzL11m/yvL42/qgB8/x186s911Q"： 指定了哈希算法 (sha384) 和哈希值。

crossorigin="anonymous"： 这个属性非常重要！ 它告诉浏览器，这个资源是从其他域（CDN）加载的，需要启用跨域资源共享 (CORS) 机制。 如果CDN服务器没有正确配置CORS，浏览器会拒绝加载资源，即使哈希值匹配。 anonymous 表示请求中不发送用户的身份信息（比如Cookie）。 如果你的CDN资源需要身份验证，可以使用 crossorigin="use-credentials"，但这需要CDN服务器和你的网站都进行相应的配置。

3. 备胎计划：fallback机制

万一CDN挂了怎么办？ 总不能让你的网站直接瘫痪吧？ 所以，我们需要一个“备胎计划”，也就是fallback机制。 当CDN资源加载失败时，我们可以加载本地备份的资源。

<script
  src="https://cdn.example.com/jquery.min.js"
  integrity="sha384-vk6g625u2wvWjWqJt548fa19v4kE5/qii6YvLzL11m/yvL42/qgB8/x186s911Q"
  crossorigin="anonymous"
>

  window.jQuery ||
    document.write(
' '
    ); // 本地备份


这段代码的意思是：

首先尝试从CDN加载 jQuery。

如果加载失败，或者 integrity 校验失败，window.jQuery 会是 undefined。

window.jQuery || ... 这部分代码会判断 window.jQuery 是否存在，如果不存在，就执行 document.write(' ')，也就是加载本地备份的 jQuery。

注意： 本地备份的资源也需要进行 integrity 校验，虽然风险相对较低，但防患于未然总是好的。

Part 4: SRI的注意事项 (避坑指南)

SRI 虽然好用，但也有一些需要注意的地方，否则可能会踩坑。

更新哈希值： 如果 CDN 上的资源更新了（比如 jQuery 发布了新版本），你必须重新生成哈希值，并更新 integrity 属性。 否则，浏览器会因为哈希值不匹配而拒绝加载资源。 这是一个常见的错误，一定要注意！

CORS配置： crossorigin 属性一定要正确设置，并且CDN服务器需要正确配置CORS。 否则，浏览器会拒绝加载资源。

哈希算法的选择： 建议使用 sha384 或 sha512。 sha256 虽然也可以用，但安全性相对较低。

动态生成的 script 标签： 如果你使用 JavaScript 动态生成 标签，也需要设置 integrity 和 crossorigin 属性。

const script = document.createElement('script');
script.src = 'https://cdn.example.com/my-script.js';
script.integrity =
  'sha384-YOUR_HASH_VALUE';
script.crossOrigin = 'anonymous';
document.head.appendChild(script);

兼容性： SRI 的兼容性还不错，主流浏览器都支持。 但是，为了兼容老旧浏览器，你可以使用 Modernizr 之类的工具来检测浏览器是否支持 SRI，如果不支持，就加载本地备份的资源。

Part 5: SRI的优势与局限性

优势：

增强安全性： SRI 可以有效防止 CDN 资源被篡改，保护你的网站和用户免受恶意代码的侵害。

提升信任度： 使用 SRI 可以让用户更加信任你的网站，因为你知道你在认真对待安全问题。

简单易用： SRI 的配置非常简单，只需要生成哈希值，并添加到 或 标签中即可。

局限性：

无法防御CDN本身被攻破： SRI只能保证浏览器加载的资源与你预期的完全一致，但无法防止 CDN 服务器本身被攻破，导致所有资源都被篡改。 因此，选择可靠的 CDN 提供商非常重要。

需要定期更新： 如果 CDN 上的资源更新了，你需要重新生成哈希值，并更新 integrity 属性。 这是一个需要持续维护的工作。

CORS配置问题： CORS 配置不当可能会导致资源加载失败。

Part 6: SRI的最佳实践

为了更好地利用 SRI，以下是一些最佳实践建议：

对所有CDN资源启用SRI： 不要只对重要的资源启用 SRI，最好对所有 CDN 资源都启用 SRI。

使用自动化工具： 可以使用自动化工具来生成和更新哈希值，例如 webpack 插件、Gulp 任务等等。

监控SRI错误： 监控浏览器的 SRI 错误，及时发现并解决问题。 你可以使用 Sentry、Bugsnag 之类的错误监控工具。

定期审查： 定期审查你的 SRI 配置，确保所有哈希值都是最新的，并且 CORS 配置正确。

结合其他安全措施： SRI 只是安全防御体系中的一部分，还需要结合其他安全措施，例如内容安全策略 (CSP)、HTTPS 等等，才能更好地保护你的网站。

Part 7: 表格总结

特性 | 描述
目的 | 确保浏览器加载的 CDN 资源未被篡改。
原理 | 通过校验资源的哈希值，验证资源的完整性。
实现 | 在 或 标签中添加 integrity 属性，指定哈希算法和哈希值。
哈希算法 | 常用的哈希算法有 sha256、sha384 和 sha512。
crossorigin | 必须设置，用于启用 CORS，值为 anonymous 或 use-credentials。
优点 | 增强安全性，提升信任度，简单易用。
缺点 | 无法防御 CDN 本身被攻破，需要定期更新哈希值，CORS 配置问题。
最佳实践 | 对所有 CDN 资源启用 SRI，使用自动化工具，监控 SRI 错误，定期审查，结合其他安全措施。
代码示例 |
Fallback机制 | 当CDN资源加载失败或integrity校验失败时，加载本地备份的资源，保证网站的可用性。例如 window.jQuery || document.write(' ')

Part 8: 总结

总而言之，Subresource Integrity (SRI) 是一个简单而有效的安全措施，可以有效防止 CDN 资源被篡改，保护你的网站和用户免受恶意代码的侵害。 虽然 SRI 并非万能，但它可以显著提高你的网站的安全性。 希望今天的讲解对大家有所帮助！ 记住，安全无小事，防患于未然！

感谢各位的观看，咱们下期再见！