Live data from Hacker News

Don't use JSON web tokens for sessions

cryto.net

41–50 of 153 posts

Re: Don't use JSON web tokens for sessions

#41

The one thing that I found scary when reading up on JWTs is that there is no way to revoke them. Of course you could check them against a list of revoked tokens on your server, but then your lose the stateless aspect. So the only remaining option to revoke a JWT is the nuclear option, invalidating all JWTs at once. This seemed like a rather large limitation to me. Related to this, the ability to encode further inform…

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.

Re: Don't use JSON web tokens for sessions

#42
post #23
post #3

How else would you do it if your backend is a REST API and you want to keep it RESTful? JWT seemed like a good solution until I read this.

Forget this article. He just doesn't like everybody uses JWT instead of cookie in any case. I still think JWS is a good choice for REST API in stateless session. I don't like to setup a redis server. What you need to do if the redis server cannot support so many users? So use JWT to keep stateless is a good choice.

> He just doesn't like everybody uses JWT instead of cookie in any case.

Why would anybody care about how you implement something in your application, unless they have a concrete reason that your implementation is less than ideal?

> What you need to do if the redis server cannot support so many users?

Scale up your infrastructure. You're need a LOT of users before this starts being an issue.

> So use JWT to keep stateless is a good choice.

The article explains why this is a bad idea... unless you can explain where the article is wrong?

EDIT: Got caught in the middle of a thought, apologies.

Re: Don't use JSON web tokens for sessions

#43

I disagree with his argument that JSON web tokens are "less secure". He even quotes this: > The only way to retrieve data out of local storage is by using JavaScript, which means any attacker supplied JavaScript that passes the Content Security Policy can access and exfiltrate it. In my opinion, it is MUCH easier to get a CSRF vulnerability than it is to bypass the Content Security Policy. Unless you can get around t…

To your last point, if you want to be able to expire "other" tokens for a user on, for example a password change, then you need to check/verify the token against a datastore on each request anyway... the same will go for access/api throttling. Which will negate some of the enhancements that "stateless" JWT gives you, as it's no longer stateless.

Of course, you can selectively "verify" the token, only doing signature validation for most requests (semi-public, browse, ...), but security-sensitive requests validate the token hasn't been revoked (checkout, profile mgt, etc), or is otherwise still valid.

Re: Don't use JSON web tokens for sessions

#44
post #36

I disagree with his argument that JSON web tokens are "less secure". He even quotes this: > The only way to retrieve data out of local storage is by using JavaScript, which means any attacker supplied JavaScript that passes the Content Security Policy can access and exfiltrate it. In my opinion, it is MUCH easier to get a CSRF vulnerability than it is to bypass the Content Security Policy. Unless you can get around t…

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…

> Using javascript to manage your sessions only the client side in any way is NOT secure.

And yet it's common practice, at least in the SPA communities with which I engage on a regular basis.

Re: Don't use JSON web tokens for sessions

#45
post #9

What I do: I use tokens (rather than cookies), but I don't use JWT, for some of the reasons listed in the post, such as "can't expire" and "data goes stale". Instead, after authenticating a user, I issue a long piece of random (256 bits of random packed into a base64 string) to the user. I use the same string as a redis key whose value is the actual user ID of the authenticated user. That way the front end can pass t…

I thought you could include a tamper-proof expiration time in the payload of a JWT token? It also seems like data-staleness could be addressed, perhaps by including a hash of relevant data and invalidating/reissuing a token when the hash changes?

You can include a tamper-proof expiration time in JWT, but you cannot early-expire or extend that JWT easily (you could always pass back a new, extended one transparently).

But in my system, I just keep expiring the redis key for 25 hours from now each time I touch it, so users' authentications expire after 25 hours (after which point they have to go back through username/password or OAUTH, etc). You can easily change 25 hours to 4 days or a month or whatever.

Re: Don't use JSON web tokens for sessions

#47
I'm not quite sure the author of the article has a solid grasp of JWT, or identity federation in general given that he compares JWT to cookies (it's more like SAML than anything else). I'd highly recommend giving the RFC [1] a once-over to see what the spec is really about.

> The correct comparisons are "sessions vs. JWT" and "cookies vs. Local Storage".

This is somewhat true, but flawed. The better comparison is "SAML vs JWT," or "CAS vs JWT." JWT is a claim assertion standard (most often used for ID claims), and should not be compared with sessions in any way. A JWT (signed by a trusted authority) is a valid way to start a session, or to hold and transmit data for sessionless communication.

> They really aren't [easier to use].

Maybe not compared to cookies, but they definitely are easier than SAML2, which they ought to replace.

> I have yet to see somebody actually explain how JWT is more flexible.

They have flexible claims which require no DTD; SAML does not. Cookies support this too, but they really shouldn't be part of the discussion.

> Server-side expiration is preferable, in fact - it allows your application to clean up session data that it doesn't need anymore

The best part of signed tokens (if you don't mess with revocation) is that you don't remember any data. You perform an identity lookup, authenticate the user, generate and sign the token, and send it off. No need to keep any data around at all, much less handle the complexity of cleaning it up.

> It doesn't, really. There are roughly two ways to store a JWT:

The way JWT solves CSRF is not by the way it's stored; it's by the way it's transmitted in an Authorization header, which can't be done cross-domain and won't be included by the browser (as cookies would). If you're not using JS, you shouldn't be looking at JWT at all; it's useless without it.

> Users don't just block cookies, they typically block all means of persistence.

Unless they're blocking JS (which would render the whole article moot anyway), then there's memory persistence for as long as the browser hasn't refreshed. This is more than enough persistence to realize the benefits of JWT (talking to multiple backends, SPA experience, etc.) Yeah, it's gone when you refresh or navigate away, but some might call that a feature. Just re-authenticate with the JWT provider and keep going.

> JWT tokens are not exactly small.

They're as small as a secure cookie: metadata header + data + signature. That's it. And they don't need to be communicated as part of the URL (though it's deliberately safe to do so), and should not be communicated via cookie (eliminates CSRF benefit).

> They are less secure

Not if they're signed and validated against trusted issuers. Which they should be. Heck, they'll even be encryptable (in a standardized way) soon. [2] Then even the browser they're sent to can't see what they contain unless it has the private key.

> You cannot invalidate JWT tokens

Yes, you can. Use revocation and check with the authority. Just because it's not specified doesn't mean you can't use long-standard methods (see CRL [3]) to achieve your design requirement.

> Implementations are less battle-tested or non-existent

As with any new technology, implementations are also new. Just like I don't have 5 years of experience with Angular 2. And a quick glance at jwt.io will show you that there are plenty of implementations available for a huge swath of languages.

Seriously, read the spec, know your use cases (JWT is not a session replacement, though it could function similarly), and learn the crypto primitives that make this secure (JWT provides verifiable integrity via signatures, not confidentiality (yet) and leaves that to other layers (until JWE)).

[1] https://tools.ietf.org/html/rfc7519

[2] https://tools.ietf.org/html/draft-ietf-jose-json-web-encrypt...

[3] https://www.ietf.org/rfc/rfc5280.txt

Re: Don't use JSON web tokens for sessions

#48

The one thing that I found scary when reading up on JWTs is that there is no way to revoke them. Of course you could check them against a list of revoked tokens on your server, but then your lose the stateless aspect. So the only remaining option to revoke a JWT is the nuclear option, invalidating all JWTs at once. This seemed like a rather large limitation to me. Related to this, the ability to encode further inform…

Tokens are created with an identifier, creation time, and expiry time. They are signed.

For web connections I use a renewal token with a long expiry (in the weeks) that is used to ensure we always have a fresh active token (in the hours). You can't get an active token with a refresh token that has a creation time less than a timestamp stored with the login details.

This allows revoking within a few hours, which is good enough for the vast majority of cases. I also maintain a pushable blacklist for emergencies - good UX for this is have the revoke button lead to a "X has successfully been logged out, this may take a few hours to affect all of our services. If it is important that they are logged out immediately click here ".

For mobile devices which need to limit requests to the server I allow passing a refresh token to most of the services, which will validate it via the server and return an active token with the response.

This works well for the applications I use it in, because I can do instant revokes, but gradual revokes are business case acceptable. Having a token does not allow you to purchase or permanently delete anything. "Super Admin" actions are done with a different system (that only appears integrated to the end user, different DB logins and everything) that requires password validation anyway.

It is not suitable for every application, but it does allow me to operate without inter-service communication for the vast majority of the time.

Re: Don't use JSON web tokens for sessions

#49
post #41

The one thing that I found scary when reading up on JWTs is that there is no way to revoke them. Of course you could check them against a list of revoked tokens on your server, but then your lose the stateless aspect. So the only remaining option to revoke a JWT is the nuclear option, invalidating all JWTs at once. This seemed like a rather large limitation to me. Related to this, the ability to encode further inform…

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.

Re: Don't use JSON web tokens for sessions

#50
post #38
post #12

This articles doesn't acknowledge where JWTs really shine: Authentication across a cloud of services, esp. a microservice architecture. JWTs allow a session to be shared across all of the services without any shared state.

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.
Post reply on HN