Live data from Hacker News

Don't use JSON web tokens for sessions

cryto.net

61–70 of 153 posts

Re: Don't use JSON web tokens for sessions

#61
post #51

Ill chime in with my $0.02 * Inability to invalidate stateless JWT tokens can be more or less be remedied with a short expiration time of the token and a token refresh flow. If a token is only valid for 5 minutes, and you can only refresh the token during that 5 minute window, it greatly reduces the attack vector. If that risk is too high, you should easily implement state with the same Redis setup that author mentio…

If you give the tokens an expiration time of 5 minutes, the application either needs to auto-request a token every 4-5 minutes automatically using a JavaScript timer, or your session times out way too quickly. If you close the tab, you will be logged out within 5 minutes. That may not be desired in many applications.

Re: Don't use JSON web tokens for sessions

#62
post #41

Earlier quoted context omitted.

JWTs can be revoked if you sign them with application_key + some_user_revocation_string. This is how password reset tokens work in Django, for example. They're signed with the app's secret key + the user's existing password hash. Once the user uses the token to change the password, the token is no longer valid.

However every service now needs access to the list of hashed passwords.

Or access to a service that has access to the hashes/revocation strings. Which puts you in a similar situation to non-JWT scenarios where every service has to phone home to check a token's validity.

I'm not saying all tokens should be made revocable in this way. I'm saying that people claiming "you can't invalidate a JWT" are overstating their case. If you really need to do invalidation, this is one option.

Re: Don't use JSON web tokens for sessions

#63
post #39

You cannot invalidate JWT tokens This is simple not true. You ALWAYS will sign your tokens with a well known secret, you could eventually even add some salt from a database to it. They are less secure Compared to what? Actually JWT will have the same secureness like Bearer Tokens or Cookies, wherever you store it, its not `less` secure. Horrible article points here. They are less secure They take the same amount of s…

You ALWAYS will sign your tokens with a well known secret, you could eventually even add some salt from a database to it. Exactly. Each JWT I generate has a salt inside which I store in the DB, and ideally the salt has accompanying data such as the datetime the JWT was generated, the IP address that generated it, etc. Now you can provide an interface that lists "sessions" and allows the invalidation of logged in sess…

Using IP addresses for session (in)validation is pretty useless now that everybody has a mobile device that moves between networks (WiFi at home, WiFi at work, 3G/4G). If you use the website while walking from WiFi to 4G you would lose session.

Re: Don't use JSON web tokens for sessions

#64

Earlier quoted context omitted.

You ALWAYS will sign your tokens with a well known secret, you could eventually even add some salt from a database to it. Exactly. Each JWT I generate has a salt inside which I store in the DB, and ideally the salt has accompanying data such as the datetime the JWT was generated, the IP address that generated it, etc. Now you can provide an interface that lists "sessions" and allows the invalidation of logged in sess…

I asked this question below, but how do you use the payload to select the correct salt from the database in order to verify the signature before verifying the signature and confirming that the payload is valid?

one way would be:

    - generate the salt
    - generate the jwt
    - use the header base64 string as the key for your database
    - store the salt with the header base64 as the key in your database
maybe?

just one idea, basically when you are > 100.000 users you barely invalidate a single token. mostly you would kill of your secret which will invalidate any token anyway. but there are numerous ways of doing so.

Edit:

to the poster after me:

actually we never needed to logout a single user. but actually our authorization is not stored in our JWT so if we want to kill a user off, we could just remove any rights from him so he gets a site where he needs to either logout or refresh (which will show him the same site again).

Re: Don't use JSON web tokens for sessions

#65
post #64

Earlier quoted context omitted.

I asked this question below, but how do you use the payload to select the correct salt from the database in order to verify the signature before verifying the signature and confirming that the payload is valid?

one way would be: - generate the salt - generate the jwt - use the header base64 string as the key for your database - store the salt with the header base64 as the key in your database maybe? just one idea, basically when you are > 100.000 users you barely invalidate a single token. mostly you would kill of your secret which will invalidate any token anyway. but there are numerous ways of doing so. Edit: to the poste…

Invalidating the site secret is my go-to strategy right now, but I have wondered how to sign out a single user across all their logged-in devices. Anyway, this idea is interesting and would be pretty straightforward to implement. Thanks!

Re: Don't use JSON web tokens for sessions

#66
post #38

Earlier quoted context omitted.

Your architecture being microservices doesn't change the problems with using JWTs (or any "session" system based on signing things): you can't revoke them. I am pretty confident being unable to revoke tokens will start to be a problem with any sufficiently large websites: you don't just need to scale in terms of traffic, but also in terms of people doing bad things. If you're at this sort of scale, adding in another…

You can (and should) use a revocation list. This is really no different than doing invalidation/revocation of stored sessions because you have the same job of sending the session/token ID out to all dependencies. But, instead of keeping a giant memory store of all sessions in sync across clusters, you only have to keep a short lived list of revoked tokens. Less noise, less memory, same difference.

Say an account gets hijacked, I want to invalidate all the sessions. How do I do it? I have no list of all the sessions that are currently out there for them.

Also: I am thoroughly unconvinced that keeping a short list of data synced across clusters is in any way easier than keeping a long list of data synced across clusters. It has the same performance requirements and the same distributability requirements. Why is this easier?

Re: Don't use JSON web tokens for sessions

#67
post #60
post #36

Earlier quoted context omitted.

I've tested many web applications, and around 80% of all applications I've tested contained an XSS of some sort or another, that number drops to around 40% if you only look at stored XSS & XSS in a get request. And to less than 10% when only looking at stored XSS. Unless you've used cookies with the HttpOnly flag XSS trivially escalates to session stealing. Do NOT store sessions in anything other than cookies with th…

if you are vulnerable to XSS your HttpOnly cookie won't help you.

You are wrong. It does. It keeps your user's session from being trivially stolen. In practise this makes successfully executing attacks harder. It's not a _nice_ thing to have, it's essential.

An example of this is an application that asks you to confirm after a POST or w/e. If your XSS vector is not in the new page, then you can't execute as an attacker automatically.

Many, many, applications (not only on the web) implement such a scheme.

A stolen session is MUCH more valuable to an attacker than only a raw XSS.

Re: Don't use JSON web tokens for sessions

#68
post #51

Ill chime in with my $0.02 * Inability to invalidate stateless JWT tokens can be more or less be remedied with a short expiration time of the token and a token refresh flow. If a token is only valid for 5 minutes, and you can only refresh the token during that 5 minute window, it greatly reduces the attack vector. If that risk is too high, you should easily implement state with the same Redis setup that author mentio…

Yes, I like this approach and it creates the opportunity for a hybrid approach between stateless JWT tokens and stateful sessions:

* JWT tokens can have a "short" expiration time, as you suggest, and within that time can be used in a stateless manner -- i.e. they do not need to be validated against a central session store, etc. * The refresh token process can use a more traditional session type configuration, where the token is checked against a central session store. The refresh can be refused if the central "session" has been revoked, e.g.

This to me gives you all the benefits of JWT (e.g. you can use federated authentication services) and the benefits of a centralized session store (e.g. easy revocability).

The main concern would be if you needed more "immediate" revocability within the stateless time frame. One solution would be to implement a "blacklist" that holds a temporary list of revoked tokens (and a token only needs to live on that list for as long as its expiration window). Alternatively, at that point you could just stick to a traditional session.

Re: Don't use JSON web tokens for sessions

#69
post #39

You cannot invalidate JWT tokens This is simple not true. You ALWAYS will sign your tokens with a well known secret, you could eventually even add some salt from a database to it. They are less secure Compared to what? Actually JWT will have the same secureness like Bearer Tokens or Cookies, wherever you store it, its not `less` secure. Horrible article points here. They are less secure They take the same amount of s…

    You cannot invalidate JWT tokens
        

    This is simple not true. You ALWAYS will sign your tokens with a well known secret, you could eventually even add some salt from a database to it.
I think one of the benefits of some (most?) JWT implementations is that it doesn't hit the database on every request - the token is only validated against a global secret.

So you can't invalidate a single user's session without invalidating all users' sessions.

Re: Don't use JSON web tokens for sessions

#70
This article seems opinionated without much substance and I disagree with many of the points listed. It also doesn't address using a JWT Token in a Cookie for Web Apps as recommended at:

https://stormpath.com/blog/where-to-store-your-jwts-cookies-...

And ignores usage of refresh tokens: https://auth0.com/docs/refresh-token

    Easier to use
JWT's are simpler when your System is composed of multiple Services as only a single Service needs to issue JWT's and provide Auth Services, all other isolated Services only needs to know how to validate a token and doesn't need other Session State or Auth configured yet are still able to provide protected Services.

    More flexible
JWT's allow for externalized, centralized Auth where the issuing of the Token can be decoupled from validating it. It lets you easily launch new Services offering Protected API's out-of-the-box without needing to configure any Auth or persistent Session state.

    Data goes stale
Services that care about stale data embedded in JWT's should hit the DB using the UserId embedded in JWT's, this is more "live" then accessing it from a Session which is stale from the moment the Session or JWT is created.

    More secure
It's not less secure, and one instance where it can be more Secure if you use RSA as the centralized Auth Service can sign JWT's with its private keys and Services validating tokens with only a public key. So JWT's can be cryptographically verified it's been issued from a central authority with access to the Private Key. Whereas authenticity of Session data is not verified and can be tampered with anyone with access to the session data store. The recommendation is to use Redis which offers weak security since it's not supposed to be accessed externally so uses a simple password which is sent plain-text over the wire.

    Built-in expiration functionality
"This is nonsense, and not a useful feature." Unhelpful Opinionated assertion slinging. Embedded expiration could be a simple constant or implemented from a Custom policy based on the User. Since this is decided by the Issuer this logic only needs to exist in one place.

    Works for users that block cookies 
"Unlikely. Users don't just block cookies, they typically block all means of persistence." Not sure where the article gets its fact checking from, but this is another opinionated assertion not backed by any sources. Cookies are blocked due to privacy issues, whereas Local Storage is used a lot more for providing rich Web App functionality. Disabling Cookies definitely does not also imply disabling Local Storage.

    They take up more space
The space trade-off is due to enabling a more performant, scalable and flexible stateless architecture.

    You cannot invalidate JWT tokens
Another strong assertion that is false. You can include any mechanism you like to invalidate tokens, e.g. you could embed a unique JWT Id (https://tools.ietf.org/html/rfc7519#section-4.1.7) to check against a blacklist loaded in App Servers memory. Your JWT implementation could have an option to "Invalidate all JWT Tokens issued before certain date" which is similar to flushing a Session storage, i.e. all JWT/Sessions created get invalidated. The simplicity and statelessness of JWT's makes it easy to apply custom generic logic.
Post reply on HN