I have been building an elm application for which I need some oppionions on the Authentication strategy part.
As of today what I am doing is after user provides login in credentials to the server reposponds with a jwt I am storing the jwt through ports to the local storage. Every time a user makes a request I am getting the jwt from the local storage and then using it to authenticate my requests to the server.
This works fine and an additions to that would be using a black list of tokens in the back end for compromised users so that I can invalidate tokens that should no longer be valide and force users to re login.
I have only recently though considered that my tokens stored on the browser’s local storage would be vulerable in the case of a xss attack since the malicious code would have access to the local storage of the user and thus would be able to retrieve the tokens. And even in the case of using refresh tokens that still is a threat from the point that I am standing.
I want to hear your thoughts on the strategy and possibly which aproach did you used.
Is it just safer to just swich back to session cookies ? Is session storage a more secury way of storing my tokens ? Are signed cookies the way to go for token storage ??
Yes, local storage can be read from javascript, so it’s an attack vector. We use http only cookies, set by the server with the SetCookie header on login/refresh which can’t be read from javascript. This cookie will automatically be sent with all http calls, so it’s easy to use. The drawback is that the application can’t see the jwt data, if you have information in it you need to duplicate it in the reply body.
Also, you can’t use it with web sockets, so in that case you have to store it somewhere that the application can read it.
We are on the same boat too (not using jwt, though). In addition we are appending SameSite=Strict option and encrypting whole Cookie payload (using Phoenix for server).
Personally I’m advocating for usage of Cookie in modern way when storing server generated tokens. It provides good guarantee around its security in modern web browsers, and allows your server to confidently control their contents and lifetime. Although, you need to have a mechanism of per-Cookie (per-session) revocation if demanded. But that is slightly off-topic since any jwt authn/z encounter the same situation, regardless of localStorage or Cookie. (Related SO answer)
With that said, I am also very interested to hear latest/secure strategy of storing tokens (jwt or otherwise) in localStorage.
Do you re-check the tokens on every API call against this black list? Often with JWT tokens, the signature is validated, but the token is not checked against a central source as it can be a bottleneck. The consequence is that black listing does not kick users out right away, but their session many continue until it expires.
I suppose you can replicate the black list over many nodes to avoid it being a bottleneck.
Another strategy I have seen employed, is to have a security threat level, and switch to more thorough checking if there is some kind of alert based on observation of network conditions.