CDN加载第三方静态资源是怎么做的?(一)

优采云 发布时间: 2021-07-30 01:20

  CDN加载第三方静态资源是怎么做的?(一)

  为了速度和减少服务器负载,我们有时会选择使用 CDN 来加载第三方静态资源。对于一些流行的第三方库,在用户打开你的网页之前,很可能会在浏览其他网站时被浏览器缓存,可以大大提高网页加载速度。

  但是CDN的使用也增加了网站的安全风险:第三方静态资源放在第三方服务器上。 CDN所有者是否有可能暗中篡改这些文件并添加恶意代码?或者CDN服务器被黑客攻击,整个文件被替换。虽然可能性不高,但也不是零。 JavaScript 可以完全控制当前浏览器页面。他们不仅可以获取页面上的任何内容,还可以获取用户输入的密码等机密信息,并获取保存在Cookie中的登录票。等等,这就是所谓的XSS攻击。

  我们需要一种机制来确保从 CDN 下载的文件没有被恶意篡改。部分下载网站提供下载文件的MD5或SHA1码,以检查下载文件的完整性。网页中有没有类似的机制?

  什么是 SRI

  子资源完整性子资源完整性缩写为SRI是一种安全机制,它允许浏览器检查从第三方下载的资源(如CDN)是否未被恶意篡改。它使用哈希值检查来确保第三方资源的完整性。只要开发者提供要下载的资源的哈希值,浏览器就可以检查实际下载的文件是否与预期的哈希值匹配。

  使用 SRI

  只需将完整性属性添加到脚本或样式标记即可。例如:

  完整性属性值以shaXXX-开头,表示后续hash值使用的hash算法。目前只允许 sha256、sha384 或 sha512 三种哈希算法,其中 sha384 更为常见。后跟对应的哈希值。

  值得注意的是,由于启用SRI需要获取下载文件的内容进行计算,所以CDN服务器需要启用跨域资源访问(CORS)支持,即返回Access-Control-Allow-Origin : * 标题。客户端需要以跨域格式加载指定文件,即添加crossorigin="anonymous"属性。据我所知,国内比较常用的免费CDN bootcdn已经支持CORS,但是百度静态CDN还没有。

  浏览器如何处理 SRI 当浏览器遇到具有完整性的脚本或样式标签时,在执行其中的 JS 脚本或应用其中的 CSS 样式之前,浏览器会先计算下载文件内容的 hash 是否该值与由完整性属性给出的值相同。如果计算结果与给定值不匹配,浏览器将拒绝执行脚本内容并报网络错误,类似如下结果:

  Failed to find a valid digest in the 'integrity' attribute for resource 'https://cdnjs.cloudflare.com/ajax/libs/normalize/6.0.0/normalize.min.css' with computed SHA-256 integrity 'VbcxqgMGQYm3q8qZMd63uETHXXZkqs7ME1bEvAY1xK8='. The resource has been blocked.

  如何计算哈希值

  这是SRI标准文档提供的示例:

  $ echo -n "alert('Hello, world.');" | openssl dgst -sha384 -binary | openssl base64 -A

  使用 OpenSSL(通常收录在 *nix 中的工具)来计算哈希值。其中 alert('Hello, world.');是文件的内容,也可以用cat Filename.js直接读取文件。

  输出H8BRh8j48O9oYatfu5AZzq6A9RINhZO5H16dQZngK7T62em8MUt1FLm52t+eX6xO,并在此基础上加上前缀sha384-

  网上也有现成的SRI哈希值*敏*感*词*,方便好用:

  CSP 和 SRI

  您可以使用内容安全策略 (CSP) 强制当前页面上的所有脚本加载标记启用 SRI。例如

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

  所有脚本标签都必须使用 SRI,浏览器将拒绝加载未启用 SRI 的脚本标签。

  对应的CSS版本:

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

  您也可以同时启用两者。

  错误恢复

  使用 CDN 时,不要忘记在尝试从 CDN 加载文件失败时加载本地版本:

  

if (!window.jQuery) document.write('')

  结束

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线