Skip to main content
1 of 2
CBHacking
  • 52.3k
  • 3
  • 97
  • 140

Security-wise, as long as you've got strong anti-CSRF protection, cookies (with Secure and HttpOnly, of course) are the way to go. They're simpler (less room for error), scale to arbitrary numbers of documents (tabs, other windows, child windows, frames, etc.), and won't get leaked in the event of XSS (though an attacker can still remote-control the session so long as the victim has the page open).

However, the "strong anti-CSRF protection" part matters a lot. There's a lot of ways to do CSRF protection, with varying degrees of security, effort, and compatibility. Sometimes people also try things that don't actually reliably work, or rely on protections they think are more universal than in reality (e.g. I once saw a site that rejected requests with the Origin header on the grounds that all cross-origin requests - even non-CORS ones like form submissions - have that, which might have been true of new versions of Chrome specifically but was by no means universally true back then, and might not even be universally true today). Additionally, while CSRF is the primary security risk for cookies, you should make sure they've got all the right flags (Secure is in theory redundant with HSTS but use it anyhow), don't allow domains including subdomains you don't need, etc.


Side notes:

the back-end will invalidate the previous pair of tokens

This surprises me, since the whole reason to use refresh tokens is that access tokens are usually JWTs, and completely stateless, which makes revocation/invalidation extremely inconvenient. They thus must have extremely short lifetimes so that a compromised token becomes useless as soon as possible. If you can reliably invalidate access tokens prior to their expiry, why bother with refresh tokens at all?

Also, problems like this are one of the reasons that making refresh tokens single-use is questionable from a UX perspective. Another is anybody on a poor connection where a refresh might reach the server but not get back to the client. While it does add complexity, consider a change such as making the old token not expire until the new one has been used once, rather than immediately upon issue. This will also avoid problems when many requests are submitted at around the same time.

CBHacking
  • 52.3k
  • 3
  • 97
  • 140