摘自这里:
如果一个跨域资源重定向到另一个新源的资源,浏览器会在重定向后将 Origin 标头的值设置为 null。这可以防止额外的混淆代理攻击,但代价是难以透明地移动支持(基于 cookie)凭据和简单请求的 CORS 资源跨域具有 3xx 状态代码,就像使用非 CORS 资源一样。可以将同源资源重定向到跨源位置(仅单跳),因为浏览器将透明地将 CORS 算法应用于此类请求并包含第一跳的 Origin 标头。
保留重定向请求的原始标头如何允许混淆代理攻击?
摘自这里:
如果一个跨域资源重定向到另一个新源的资源,浏览器会在重定向后将 Origin 标头的值设置为 null。这可以防止额外的混淆代理攻击,但代价是难以透明地移动支持(基于 cookie)凭据和简单请求的 CORS 资源跨域具有 3xx 状态代码,就像使用非 CORS 资源一样。可以将同源资源重定向到跨源位置(仅单跳),因为浏览器将透明地将 CORS 算法应用于此类请求并包含第一跳的 Origin 标头。
保留重定向请求的原始标头如何允许混淆代理攻击?
那一段写得很简洁,在第一句话中使用“重定向到新来源的另一个资源”是不太正确的。
这是一个简单的人为示例。假设您是恶意的,并且有一个 Web 应用程序通过 CORS 使用特权 API 的服务,因此该 Web 应用程序的 Origin 受到特权 API 的信任。假设您想访问该特权 API 背后的数据,但您的 Origin 当然不受信任。
您创建了一个通过 CORS 提供的简单有用的服务,并且您让 Web 应用程序将您的服务包含在一个页面中 - 任何页面 - 在其受信任的 Origin 下。该页面不需要访问特权 API。
(当然,一旦你进入受害者的页面,你可以为所欲为,但请耐心等待。)
如果您决定将 CORS 服务从发布带有一些数据的 200 更改为向特权 API 跨资源域发布 3xx,这会产生信任问题。
实际的 Origin(嵌入您的资源的页面)将受到特权 API 的信任。但它没有发出请求,并且它可能不想在这个特定时间点与特权 API 对话。
相反,您发出了重定向,虽然您在一定程度上受到 Origin 的信任,但您不受特权 API 的信任。如果浏览器跟随您的 3xx 并沿 Origin 发送,您将非法捎带特权 API 给予 Origin 的信任。
浏览器要做什么?一个合理的答案是根本不遵循 3xx,但这将不允许使用不关心信任的用例。使用“null” Origin 发出请求允许这些用例,但防止利用沿着原始 Origin 标头发送所允许的信任。
从 CSRF 防御的角度来看 Origin 标头。
假设a.com主机...
如果跨域重定向后保留了 Origin,则可能发生以下 CSRF 攻击:
Origin: https://a.com
。Origin: https://a.com
.a.com服务器处理请求,因为它认为它来自a.com,这并不完全准确,因为......
a.com向b.com发出 CORS 请求这一事实并不意味着它完全信任b.com。
这在相关的 Chrome 错误中进行了讨论:https ://bugs.chromium.org/p/chromium/issues/detail?id=465517
如果 Origin 标头包含重定向链中所有来源的列表,则可以构建安全地容忍跨域重定向的应用程序。不幸的是,浏览器供应商从未实现过这一点。来自问题中引用的同一CORS for Developers 文档:
尽管 CORS 规范暗示您可以在 Access-Control-Allow-Origin 标头中列出多个来源,但实际上所有现代浏览器只允许一个值。多值语法旨在允许列出重定向链中的所有来源,正如 RFC6454 所允许的那样,但这从未实现。