要求 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.com
Access-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 的哈希。