Live data from Hacker News

Stop using JWT for sessions (2016)

cryto.net

41–50 of 255 posts

Re: Stop using JWT for sessions (2016)

#41
post #23

From my time browsing HN, the consensus seems to be "don't use JWTs". What is the preferred method of client authentication for simple APIs these days?

OAuth access tokens? The difference being that JWTs contain information directly, as well as an access token to hit any APIs, while an access token contains no information on its own - thus solving the revocation issue.

Now I don't think anyone really uses JWTs for API authentication, or they should not at least. APIs should still be gated by access tokens.

Re: Stop using JWT for sessions (2016)

#42
post #23

From my time browsing HN, the consensus seems to be "don't use JWTs". What is the preferred method of client authentication for simple APIs these days?

Disclaimer: not a front-end dev.

I'm not sure what the issue is with a simple session token, to be honest. OWASP have guidelines on this that cover the bases pretty well, I think.

Store hashes, not tokens directly.

Expire them server side.

Don't accept user input (within reason). You generate and offer the tokens, you know what they look like, you can bounds check / sanity check appropriately.

Perform some additional checks as necessary (e.g. invalidate a session if remote IP changes).

If you have more security critical parts of the infrastructure, require re-authentication and more short-lived sessions for those. The obvious example would be how Amazon pretend you're "logged in" until you go to click My Orders, then you get auth gated.

I tend to think that people over-complicate this stuff a lot as a premature optimization for scaling.

A simple python script backed with some DB will do hundreds of hits a second to an auth service without really trying. If you need more than that, optimize. If you need more than 10k hits a second on a regular basis then you're probably at the point of hiring someone who knows this stuff.

Just my 2c.

Re: Stop using JWT for sessions (2016)

#44

Earlier quoted context omitted.

How do you encode it in such a way that you can invalidate individual tokens? How do you distribute that information among your services?

In the past, I've compared the "iat" (issued at) value with a column in the users table called "invalidate_tokens_before". If I need to invalidate tokens for a user (for my use case, it would always be all tokens for a user at once), I just touch that timestamp column. True, it still required a db lookup (one that happens anyway), but I found that easier to manage than storing and managing session tokens.

Doesn't the author cover this in their rebuttal (http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-fo...), "Your blacklisting/revocation server goes down, now what?".

Everything from there goes to "Congratulations! You've just re-invented sessions (only with a less battle-tested implementation) and gained nothing in the process"

(Sarcasm is from the author's post, not mine!)

Re: Stop using JWT for sessions (2016)

#45
Many in the comments are curious about blacklisting JWTs. No, you don't need to put the whole token on a blacklist. Give your tokens reasonably unique JTI claim[1] and put the affected JTIs on the blacklist.

The benefit of JWTs is that token blacklists are usually much shorter than hypothetical token whitelists.

[1] https://tools.ietf.org/html/rfc7519#section-4.1.7

Re: Stop using JWT for sessions (2016)

#46
If an attacker can read the user's localStorage you have much bigger issues to worry about: XSS, physical access, no TLS, etc. With any of those, the token is the least of your concerns; an attacker can make API calls, read the data, etc anyway, no matter if its JWT or sessions.

So, IF (which is a big if) you implement everything correctly then you have to do two "extra" steps with each tech:

- Blacklists (or Whitelists). You _do_ need these, because you want users to be able to logout. Then it's a lot more like sessions... oops.

- CSRF protection for sessions. These become trickier to manage in SPA and just become sort of a "token" that you need to refresh on each call... oops.

It seems that the shortcomings of each technology makes it to lean towards the other. The good news is that both of them are theoretically secure, the bad news is that to reach that level you have to do a lot of work (on both!) with a lot of room for error.

That is why I personally prefer JWT with SPA and CSRF with traditional servers, since the amount of new code that I have to write is a lot lower so chances for error are quite lower. For instance, see the (very brief) documentation of the CSRF for my project server.js: https://serverjs.io/documentation/router/#csrf-token . If I had more time I'd write something similar for JWT.

Re: Stop using JWT for sessions (2016)

#47

Can someone explain the Cookie vs LocalStorage thing? You can access cookies from Javascript, so how is localstorage worse? Assuming an attacker can execute arbitrary js in the browser (the model provided by the article). edit: Thanks for the answers - httponly, makes sense.

https://portswigger.net/blog/web-storage-the-lesser-evil-for...

(It not only explains what others have said about httpOnly, but it also goes more in depth on the tradeoffs between the two.)

Re: Stop using JWT for sessions (2016)

#48
post #17

Top reason for me always was : > You cannot invalidate individual JWT tokens And there are more security problems. Unlike sessions - which can be invalidated by the server whenever it feels like it - individual stateless JWT tokens cannot be invalidated. By design, they will be valid until they expire, no matter what happens. This means that you cannot, for example, invalidate the session of an attacker after detecti…

Why not just "invalidate" the client? At best, you're making your application "safe" for 900ms or whatever the expiry date is.

I bruteforce a password for your JWT-enabled app. Then I have a token. Copy the token from my browser ( usually just open Network tab at the inspector and copy the headers for the request ). Then I store the token at my server and make it execute a request to the app on intervals to prevent from expiring ( reissue ) the token.

How can you invalidate my server now?

Re: Stop using JWT for sessions (2016)

#49
post #14

Top reason for me always was : > You cannot invalidate individual JWT tokens And there are more security problems. Unlike sessions - which can be invalidated by the server whenever it feels like it - individual stateless JWT tokens cannot be invalidated. By design, they will be valid until they expire, no matter what happens. This means that you cannot, for example, invalidate the session of an attacker after detecti…

Not true. Encode a token and validate it against a constant, which you change in case of a compromise.

Doesn't the author address this in their "Why your solution doesn't work" flowchart? Everything ends up a reinvention of traditional sessions, only with a less battle-tested implementation.

Re: Stop using JWT for sessions (2016)

#50
post #44

Earlier quoted context omitted.

In the past, I've compared the "iat" (issued at) value with a column in the users table called "invalidate_tokens_before". If I need to invalidate tokens for a user (for my use case, it would always be all tokens for a user at once), I just touch that timestamp column. True, it still required a db lookup (one that happens anyway), but I found that easier to manage than storing and managing session tokens.

Doesn't the author cover this in their rebuttal ( http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-fo... ), "Your blacklisting/revocation server goes down, now what?". Everything from there goes to "Congratulations! You've just re-invented sessions (only with a less battle-tested implementation) and gained nothing in the process" (Sarcasm is from the author's post, not mine!)

I don’t think of JWT as a replacement for db lookups or storage, but they do provide a convenience in not having to store and manage all sessions in the database[1]. I’ve done it both ways, and as long as you’re careful about a few of the potential security issues with JWT (solve it once, put it in a reusable module), it actually does save a considerable amount of code and complexity on the server side.

Also, in my case, "your blacklisting/revocation server goes down" means the whole application is down anyway, so that's kind of a moot point.

You may disagree, and there are valid reasons to avoid JWT. I'm just saying that under the right circumstances, it can be useful.

[1] The author claims that JWT isn't any easier, but then later says things like "Expiration can be implemented server-side just as well, and many implementations do". That's true, but it is something extra you have to implement yourself, i.e., not easier (for that feature at least).

Post reply on HN