Live data from Hacker News

Stop Using JWTs

gist.github.com

71–80 of 335 posts

Re: Stop Using JWTs

#71

I ain't never gonna stop!

I might stop if somebody linked to an article pointing out an actual problem, rather than making vague and/or incorrect/misleading assertions.

Let me bite, as someone who usually hates JWT but sometimes uses it, including for browser auth.

Why JWT is bad: it's a cargo cult solving a non-existent issue in a more complicated way than necessary. An HTTPOnly session cookie containing just a random ID is shorter and easier to handle.

Why JWT is also bad: a typical way to use it exposes too much attack surface. Almost every JWT library has way too much functionality, supports multiple algorithms, and many people are too sloppy with their dependencies, so you probably haven't read every line of code that runs in your auth.

How to use JWT safely:

1. Have a use case that cannot be easier solved with just a random session identifier. For example, one party creates tokens and another unrelated party verifies them. If same party issues and validates tokens, you better have a super high load, unique use case -- but then you're senior enough to not take random advice from strangers.

2. Write your own JWT handling code. It's literally a few lines of code to create tokens and a few dozen to validate. Only implement the exact algorithms and claims you use.

3. In a typical scenario, JWT should still carry something like a user ID which you should immediately verify against a database. Stateless sessions doesn't mean no DB lookups on validation. If you DO authenticate based on the token alone, the token should be super short lived (seconds or single digit minutes).

Re: Stop Using JWTs

#72

JWTs are for authenticating an already trusted system with another system. Using them as the primary source of truth is an anti-pattern like the blog post is actually saying.

It's not a blog post, it's a post on Github Gist.

Re: Stop Using JWTs

#73

Security doesn't start or end with JWTs. A user wants to access a read-only resource with an invalid JWT? Envoy bounces it without passing the request through to the backend. Valid JWT? Let the request through without having to look up any session information. No DB, no cache, no session server hit. Fast. A user wants to change a password, email address, or add an authenticator? First, require a password, second, req…

> look for the JWT access token in a revocation list that is only accessed during sensitive, infrequent, requests

I've clearly spent too much time working with data covered by HIPAA because this sentence gave me a brief bit of panic. The vagueness and extent of what it technically covers means it's far safer to just assume literally everything about your users needs maximum security.

Re: Stop Using JWTs

#74
> You can't securely have truly stateless authentication without having massive resources, see the cryto.net link above.

I don't think the cryto.net post really explains why this is true (at least in a way that would be made different by "massive resources").

Re: Stop Using JWTs

#75

Earlier quoted context omitted.

Yeah of course, but how does that relate to my point? With JWTs you don'T have a list of valid tokens as state, but only a list of invalid ones (revoked). But the list of revoked tokens in the last X hours (where X is your token lifetime) is always going to be smaller than the list of active sessions given a large enough user base. Hence my original point stands, that the lookup and storage costs are lower than on se…

> With JWTs you don'T have a list of valid tokens as state, but only a list of invalid ones (revoked). Yes, and a lookup operation is a lookup operation. Your database or data structure used for storing the sessions/JWT revocation entries won't really care whether you look for things that are active or things that are inactive/revoked. If you store it in the right database, both lookups will be O(1), so it is the sam…

The story changes if you have a distributed database. replicating a smaller revocation list (that is append only) that will never be more than a couple of MB, is easier to do accross distributed nodes around the world than keeping a larger, session state db replicated. Heck, your revocation list can even be public (it contains only a list of substring of a few bytes of hashes).

Syncing sessins can be done, no question, I would just think JWT+revocation db is easier to implement, yet robust.

Re: Stop Using JWTs

#76
I remember learning to make sites back around 2019 and seeing so many blog posts and hype around JWTs. It seemed like "this was the way to do it!" But I couldn't understand why session cookies weren't the better, simpler solution. I just used session cookies. Nice to be vindicated in retrospect.

Re: Stop Using JWTs

#77
JWTs are fine, seems a bit sensationalist title...

Some nice topics to talk about instead:

- When to use an encrypted value (and symmetric or asymmetric), vs. a random (but secret) value, vs. a signed value (readable but not tamperable)

- Where to put these values (memory, localStorage, cookies)

- How to make sure these values don't last forever, and whether you need to be able to revoke them (make them invalid before their natural expiration timestamp)

Re: Stop Using JWTs

#78

Earlier quoted context omitted.

I edited my comment after I posted it to clearify you do this on a per-identity basis. I.e. every user/identity has a minimum_issued_at field. A user can "sign out from all devices", and that will simply update minimum_issued_at with $NOW. You are not throwing out a lot of babies with the bathwater if you would do it in a case of a known attack. You would invalidate ALL tokens of a user, which is a sane default espec…

Thanks for the correction, I didn't think about this approach and it sounds like it should work. The only comment that I have that if you are already querying users table (or collection in case of NoSQL or whatever), you might as well have a sessions table/collection in the same database/storage and query them together. It seems that difference is not that big. The purported advantage of stateless sessions is that yo…

Think a small (as in client base), but distributed system - i.e. Asia/EU/US locations of a webshop. You can easily replicate/cache your products from a central server, and reuse the cache from the localized ones. But each and every web request would have to be authenticated against a central db somewhere around the world. It is just easier if each node can just validate the JWT themselves by using crypto. All they need to do is maintain a revocation list locally. Now, your revocation list is append-only, can be publicy available and never going to be more than a couple MB. Very easy to replicate/cache this. I can't say the same for a session database.

Re: Stop Using JWTs

#79
post #37
post #19

Earlier quoted context omitted.

> if you have to check an identifier for revocation on every request you could just use an opaque session ID and look that up on every request instead! One reason could be the size. A revocation list only needs to keep session IDs of recently logged-out sessions, for which the token's TTL hasn't yet expired. It may be a much smaller list than a list of every active session. Also, a JWT (or a Macaroon, etc) can store…

As someone who operates a PostgreSQL database containing 27 billion SSL certificates, each 1-2kb each, with a bunch of secondary indexes that get inserted in random order, I find it pretty incredible that people see the need to optimize their session database. At what scale does the size of the session database actually matter? Those stateless tokens may be "unforgeable", but they are replayable, and if you're not mi…

I think one meaningful case is when you have services in very different locations and you would rather than having to make a request to a session store in a single location, replicate the data to each location for better latency, so in this case a revocation list.

Re: Stop Using JWTs

#80

One of the articles that TFA links to [0] contains the following paragraphs: > 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 detec…

>> You are essentially powerless, and cannot 'kill' a session without building complex (and stateful!) infrastructure to explicitly detect and reject them, defeating the entire point of using stateless JWT tokens to begin with. > I'm not sure that this is entirely true. You can be sure it is not true, because it is utter BS. JWTs have an "iat" timestamp field (issued at) and in the described case that an attacker has…

> your validation logic simply should refuse any token with iat makes no sense

... ok now it does :) your now is not now, but a stored value

Post reply on HN