EDIT: The title not being clear enough (I thought it was implicit): This article is about the "storing tokens in localStorage or in cookies for SPAs" debate. It is NOT about using cookies to store general purpose data.
I'm a tad tired of reading "dont use localStorage, it's not secure". Why ? Oh, yes "its accessible in JS". Let me tell you how this seems to be an overrated argument to me.
If someone can run arbitrary JS on your website, do you really believe a peremptible JWT will necessarily be the only thing that can be exploitable ?
Personally, I'd go with something far more interesting to me: Collecting what user are typing in password boxes. Or just performing the requests that interest me directly from their browser. Those exploits are even easier to write when using cookies, given that you dont have to guess where is the token stored nor how to use it.
- Protecting against CSRF is not that easy, and beginners are not even aware of it.
- Implementation of multiple authentication is harder (if you're writing a signle API that must be usable in multiple websites)
- You cant control them (easily tell if you're logged-in, read associated data, ...)
- CORS is harder with them.
You're worried that one of your dependencies might be accessing your localStorage maliciously ?
Well, that's not a strong valid argument, you could just prevent it to do so like that when bootstraping your application:
const storage = localStorage; delete localStorage;
And voilà ! There is no more localStorage exposed in your window, but you still can access your tokens via the "storage" local variable (of course, you must keep it in a private scope).
These two lines of code will protect you from the most obvious and common exploit that localStorage is blamed for.
(of course you could imagine spying tokens by overriding fetch or equivalent, but that also is mitigable... its about preventing 99% of exploits, this is not strong security)
If other parts of your app need to access local storage, you could set
window.localStorage to a proxy that only lets the user access non critical parts of your local storage, leaving your precious tokens out of their sight.
I think that the web has more suffered (and is still suffering) from CSRF attacks compared to stolen JWTs, so dont tell me that https cookies are the secure way to go. Unless you're writing ultra-secure and highly-reviewed code, no, they're not. Its easier to make mistakes with cookies compared with localStorage tokens.
Just to be clear: I dont prefer one over another... I'm just saying that this debate is a bit useless, both approaches having their own sweetspots and weakspots.
I'm just sick of people explaining you otherwise with a condescending tone just because they think they've understood all there is to know by saying "its accessible by JS". Or because they've read somewhere that localStorage tokens might be considered as a potential security leak by some. Give me a break. The world is about nuance, not about dogmas.
Happy to hear what you think of this in the comments.