tl;dr the Cookie-to-header-token method can't work due to the CSRF token cookie not being readable by the client in any way. Is sending the token in a header, and having the client save it in a cookie immediately considered a valid alternative?
I am trying to find a way to mitigate CSRF in a cross domain scenario where the client stores all the static assets (including the index.html entry point) and the server is in a completely different domain (no shared parent domain).
I was looking at first at the Cookie to Header Token method, but it seems that both the client and the server must be on the same origin.
(The server issues a JavaScript readable cookie named XSRF-TOKEN, the client, being on the same origin, can read the cookie, then add a header on all subsequent calls, e.g. X-XSRF-TOKEN, this is how for example Angular handles CSRF, this all works great as long as both are on the same domain or share some parent domain)
However, it seems that for cross origin domains, this won't work.
Assumptions
XHR can't access the
Set-Cookie
header. XHR doesn't allow looking at response cookies. Even with the most permissive CORS headers, and even if not set as httpOnly, it's blocked by the browser. (It will also hide the Set-Cookie header if looking in dev tools) (https://fetch.spec.whatwg.org/#forbidden-response-header-name)Other domain's cookies are not JavaScript accessible, obviously, even if not set as httpOnly, and even if the XHR request is
withCredentials=true
and will send that cookie in future requests to the cookie's domain (assuming matching header in the server) it's never JavaScript accessible, and we all are grateful for that.Setting the Cookie Domain to that of the XHR's Origin doesn't work. What if the server will set the cookie to the client domain? It is impossible to set a cookie for a different domain of course, (https://www.rfc-editor.org/rfc/rfc6265#section-4.1.2.3) and this includes XHR, e.g. if I have XHR in page
ui.example.com
make a request to a server inapi.example.net
, and the server sets a cookie with domainui.example.com
, the user agent seems to reject the cookie from what I've seen, (I assume since the server and the page itself are still in different origins), although the XHROrigin
is the same as theDomain
that was set in the cookie, this won't work, and I'm sure there are good reasons for it.
The only method I can think of at the moment is having the server send the CSRF token as a header that the XHR can read, the client will then store it via JavaScript in a client domain scoped cookie, then the rest will work as in the Cookie to Header Token method above.
Questions
Are any of my assumptions above incorrect?
Is there any authoritative source that defines the alternative approach above as secure? Does it have significant disadvantages over the same-domain cookie-to-header-token method?
Are there any other ways to securely mitigate CSRF for this use case?
Related Answers I Reviewed
I went through the following questions / answers but none of them felt like an authoritative answer to my question, I may have missed to read between the lines so my apologies if this is an exact duplicate