如果 CORS 请求不需要身份验证,为什么我不能在没有 cookie 的情况下发送它?

信息安全 访问控制 科尔斯
2021-09-08 23:52:00

在过去的 N 年里,我多次需要我自己的页面 (ABC.com) 从不同的来源 (XYZ.com) 获取一些数据并显示它(全部在 JavaScript 中,没有服务器获取)。

这不起作用,因为 XYZ.com 的Access-Control-Allow-Origin标题中没有 ABC.com。如果标头确实包含 ABC.com,那么我的浏览器的 XYZ.com cookie(即身份验证 cookie)将与请求一起发送到 XYZ.com。我完全理解如果浏览器没有访问权限,为什么浏览器会阻止 ABC.com 向 XYZ.com 发出经过身份验证的请求。

但在我的所有场景中,向 XYZ.com 发出的请求都是可供公众使用的资源,不需要身份验证/cookie,任何人都可以获取它们。我知道有解决方法(有 ABC.com服务器从 XYZ.com 请求数据)。或者 XYZ.com 可以发布 JSONP。但在我的情况下,有时我从本地文件系统提供我的文件,所以没有服务器。从服务器获取它是一个 PITA。最后,我没有控制 XYZ.com,也不能强迫它也发布 JSONP。n 问题的核心 - 如果 ABC.com 不在 XYZ.com 的访问控制标头中,为什么浏览器不允许 ABC.com 的 JavaScript 向 XYZ.com 发出请求但不发送任何 XYZ。 com 的 cookie 存储在该用户的浏览器中。如果浏览器制造商这样做,这是否会使用户面临某种其他漏洞?因为我什么都想不出来。我错过了什么?只是人力的事情,编程会花费太多时间吗?

2个回答

历史

最初的 XMLHttpRequest 实现没有“允许凭据”的概念——所有请求都附加了凭据。当然,如果允许跨域这样做是非常危险的,所以 XMLHttpRequest 最初只允许同源。添加 CORS 后,他们希望最大限度地减少更改以降低意外后果的风险,因此保持非 CORS 站点的同源行为是有意义的。

意外的身份验证

当请求没有“允许凭据”时,浏览器可能会无意中包含凭据。浏览器无法避免的一个示例是网络限制——例如访问 Intranet 站点的 Internet 站点。可能还有其他示例,例如客户端证书。如果某些浏览器仍然附加客户端证书,即使是在非凭据请求下,我也不会感到惊讶。

安全第一

上述原因并不那么强烈。CORS 本来可以设计为默认允许非凭据请求。然而,这是风险更大的设计。在开发 CORS 时,浏览器设计人员非常了解安全问题,并选择实施风险较小的设计。

我相信它是浏览器/服务器生态系统中分层防御的一部分,有助于打击跨站请求伪造 (CSRF)

参考:

维基百科 OWASP

基本上,浏览器在请求它们之前不知道哪些 Web 资源可能需要或不需要 cookie 或 auth。根据 ABC.com 的说法盲目地发送 cookie,意味着浏览器不知道用户是否想在 XYZ.com 上进行身份验证。因此,如果没有另外说明,它会在谨慎方面犯错。

从你的第一段,你已经明白了。因此,现在假设 ABC.com 托管一个留言板(例如),并且恶意用户发布了一些 javascript。当受害者阅读该消息时,他们的浏览器现在从 ABC.com 读取并执行“只是 javascript”,而 ABC 和 XYZ 既不认可也不知道任何事情。基本上,浏览器无法分辨出什么是“来自”ABC.com 的所有者,以及可能由某些不良行为者(可能通过托管广告网络)注入的内容。

在任何情况下,都可以发出跨域请求,但不应自动对其进行身份验证。

例如,假设您登录到 MyBank.com,然后访问 ABC.com,BadGuy 已经在您收到的广告中隐藏了一个 JavaScript 请求,其内容基本上是“http://MyBank.com/xfer-money-to= BadGuy&amount=100.00" 如果您的浏览器发送了身份验证 cookie,BadGuy 可能会让您的浏览器执行您不​​想要的操作。示例显然过于简化,但您明白了。

[编辑]另外,刚刚发现这个已经存在的答案,我认为它比我的更好。添加作为参考。 安全堆栈交换