tl; dr Cookie-to-header-token 方法无法工作,因为客户端无法以任何方式读取 CSRF 令牌 cookie。是否在标头中发送令牌,并让客户端立即将其保存在 cookie 中被认为是有效的替代方案?
我试图在客户端存储所有静态资产(包括 index.html 入口点)并且服务器位于完全不同的域(无共享父域)中的跨域场景中找到一种缓解 CSRF 的方法。
我首先查看的是Cookie to Header Token方法,但似乎客户端和服务器都必须位于同一来源。
(服务器发出一个名为 XSRF-TOKEN 的 JavaScript 可读 cookie,位于同一来源的客户端可以读取 cookie,然后在所有后续调用中添加标头,例如 X-XSRF-TOKEN,例如 Angular 的处理方式CSRF,只要两者都在同一个域上或共享某个父域,这一切都很好)
但是,对于跨域域,这似乎行不通。
假设
XHR 无法访问
Set-Cookie标头。XHR 不允许查看响应 cookie。即使使用最宽松的 CORS 标头,即使未设置为 httpOnly,它也会被浏览器阻止。(如果查看开发工具,它也会隐藏 Set-Cookie 标头)(https://fetch.spec.whatwg.org/#forbidden-response-header-name)显然,其他域的 cookie 不是 JavaScript 可访问的,即使没有设置为 httpOnly,并且即使 XHR 请求是
withCredentials=true并且将在将来的请求中将该 cookie 发送到 cookie 的域(假设服务器中的匹配标头),它也永远无法通过 JavaScript 访问,并且我们都对此表示感谢。将 Cookie 域设置为 XHR 的 Origin 不起作用。如果服务器将 cookie 设置为客户端域怎么办?当然,不可能为不同的域设置 cookie(https://www.rfc-editor.org/rfc/rfc6265#section-4.1.2.3),这包括 XHR,例如,如果我在页面
ui.example.com制作中有 XHR对服务器的请求api.example.net,并且服务器设置了一个带有域的cookieui.example.com,用户代理似乎拒绝了我所看到的cookie,(我假设因为服务器和页面本身仍然处于不同的来源),虽然XHR与 cookie 中设置Origin的相同,Domain这是行不通的,我相信它有充分的理由。
目前我能想到的唯一方法是让服务器将 CSRF 令牌作为 XHR 可以读取的标头发送,然后客户端将通过 JavaScript 将其存储在客户端域范围的 cookie 中,然后其余的将像在上面的 Cookie 到 Header Token方法。
问题
我上面的任何假设都不正确吗?
是否有任何权威来源将上述替代方法定义为安全?与同域 cookie-to-header-token 方法相比,它是否有明显的缺点?
有没有其他方法可以安全地缓解这个用例的 CSRF?
我审查的相关答案
我经历了以下问题/答案,但没有一个感觉像是对我的问题的权威答案,我可能错过了字里行间的阅读,所以如果这是完全重复的,我深表歉意