My understanding is the use of JWTs for session management is 99% of the time bad (tldr: you think you get "stateless" sessions but in reality you still need server side state for useful features like logging out); but its use for auth (i.e. via OIDC) is a normal and good use case.
> in reality you still need server side state for useful features like logging out
im curious about this. normally 'logging out' just involves deleting the secure http-only cookie where the jwt was stored. is there something I'm missing here?
Access revocation: sometimes it's critical to block access to an issued token, without trusting the client to comply with revocation, especially for malicious cases.
Enforcing this implies to implement access control on each (critical) request, giving little advantage to a self contained token compared to a pure stateful signed session token.
With ordinary sessions you need to store all active sessions in server. Sessions might be long-lived, may be eternal.
With JWT you need to store forcibly terminated active sessions in server. Those sessions are short-lived. So basically it's empty map.
Another solution with token is to change server key and force all short lived sessions to reauthenticate. It is not very nice, but if that's an extremely rare scenario, it might be appropriate to get rid of checking each request while still supporting forcible logout.
Yeah, if you need that kind of control over token access, then im not certain a jwt is the right tool for the job. For most use-cases a short-lived jwt is fine, as it expires in a matter of minutes, or even seconds, depending on configuration.
The ability to logout existing sessions (typically either via a manual user action or automatically upon changing/resetting their password) is a desirable feature in essentially all applications where user accounts can be compromised.
You can kind of fake this by using a short-lived JWT and constantly refreshing it, but this:
1. Massively increases server strain and bandwidth usage
2. Has problems with users less reliable connections (they'll be randomly logged out all the time)
3. Makes "Remember Me" style features impossible (unless you use a server-side store for that, which brings us back to it not being stateless)
> 1. Massively increases server strain and bandwidth usage
A short-lived JWT that fits into an HTTP Header is not going to _massively_ increase your bandwidth usage. At most, you will end up with a single refresh request every few minutes as each short-lived JWT expires.
> 2. Has problems with users less reliable connections (they'll be randomly logged out all the time)
Usually if your request failed due to a bad connection, the client wouldn't be designed to automatically log out the user. That would be just terrible UX.
> 3. Makes "Remember Me" style features impossible (unless you use a server-side store for that, which brings us back to it not being stateless)
Incorrect. A short-lived JWT tied to a refresh token allows for a remember-me style feature by checking account access when issuing a new JWT token.
The skiny is that you place a copy of some monotonic counter inside every JWT you issue, you keep track of the counter server side and compare with each request's JWT copy + some delta (which is the equivalent of maximum number of concurrent sessions you wish the user to have).
Don't you need to hit the DB anyway to fetch authorization data like user role? Clearly you aren't going to store it in JWT or you face the issue with invalidation. But fine, cache it in Redis. Problem solved.
This conversation comes up all the time when discussing JWTs, and unfortunately I think the issue is usually way overblown:
1. I don't believe there are any real security issues regarding logout if JWTs have a sufficiently short expiration time.
2. The reason this issue comes up is because of compliance audits, who demand that as soon as the user logs out, that the supplied token becomes invalid. However, if the JWT is adequately discarded from the client, the fact that the JWT is still valid for another ~5-10 minutes or so is only a security risk if the token has already been stolen. The fact of the matter here is you really aren't protecting against a new attack vector with this "must immediately revoke tokens on logout" rule.
3. Despite my beliefs with #2 (and I'd love to hear an argument why this isn't valid), good luck trying to convince an auditor about that fact, who often love finding minor/mundane issues to justify their existence. So you'll still need to maintain a small blocklist, but the data in that list is usually very small (most users never log out these days) and can often be replicated in memory to each server.
I agree with your assessments, and your reply makes sense in the context of the above comments. Simply so that any readers arriving here that didn’t read the article arrive here, I just want to remind that these are not the fundamental complaints of the actual article itself, and are also unrelated to the proposed solution.
This is solved with a revocation list, which only needs to contain the tokens issued within the last ~5-10m for which there is a reason for revocation. Add to that a revocation list for access tokens, which are typically 24h.
The sum of both lists is vastly smaller and easier to manage than distributing session state and maintaining it server side for every single user.
I'm sure there are employees out there that have their self destruct scripts ready to go. If they are ever terminated they have 10 minutes of token validation time to blow everything up.
I believe they are mentioning the fact that the server cannot unilaterally log the user out in a "naive" JWT-based implementation without storing and checking a token blocklist - which makes the session no longer stateless.
I can see that. I suppose when people say they need 'server-side session storage' I start thinking of app state, but in reality it could be as simple as storing a jwt refresh token that would be considered valid.
It matters in the context of folks that are trying to do a serverless architecture, sold on the idea that JWTs don’t require anything more than a function to issue auth
Use the flaws to exploit an AWS, Azure or Google product?
And if you can't, are they really flaws? Or is this just an issue of some people implementing the standard badly, and they need to be taught to use better libraries?
It's certainly possible to use JWT correctly, and with sufficient resources put towards auditing, most flaws will be caught. This doesn't make it a good design.
Sounds like trying to convince people to abandon IPv4 for IPv6. Even though IPv6 is a superior technology its still a tough sell. Arguments for doing nothing because change is hard make for bad technology considerations.
I am not stating any opinion upon JWT or alternatives.
Until then, this is pretty much noise.