Live data from Hacker News

Stop Using JWTs

gist.github.com

161–170 of 335 posts

Re: Stop Using JWTs

#161

This links to some other blog post for the bulk of it's 'why', and that blog post mostly seems to be annoyed about "You cannot invalidate individual JWT tokens". Which every time I've implemented, the general guideline is to check for invalidated nonces somewhere. Which resolves that random blog posts second point too. >The JWT specification itself is not trusted by security experts. This feels like it needs more evi…

Right, but once you're checking for invalid nonces, your token format is now stateful; it's lost the primary benefit of statelessness, which is continuing to function under network partition between the application server and the token state store.

Re: Stop Using JWTs

#162
Every once in a while an article with a sensational title against JWTs pops up in here and I have to wonder if something new was discovered. But nope. It always boils down to the same "can't invalidate it" complaint, which can be addressed with a viable deny list structure (simple in-memory or runtime index, bloom filter, trie). Then there are the vague "it's insecure" claims which when looked at closely, come down to "some people use it wrong".

Re: Stop Using JWTs

#164
Is this at all coherent...? The author really seems to be comparing cookies to JWTs as if they exist in the same category, but it really is apples to oranges here. In fact, one of the first articles they link to spell that out explicitly:

> A lot of people mistakenly try to compare "cookies vs. JWT". This comparison makes no sense at all, and it's comparing apples to oranges - cookies are a storage mechanism, whereas JWT tokens are cryptographically signed tokens.

And yet the author seems not to have noticed, or something? Odd.

Re: Stop Using JWTs

#166
post #46

In sessions vs. JWT revocation lists, there is an argument in favor of JWT revocation lists. JWTs have a limited expiry timestamp, so you only ever need to maintain a revocation list for tokens not expired yet. Given that you probably only have a fraction of JWTs revoked compare to valid JWTs in circulation, you only need to query a very small dataset for each request. When using sessions, your list of valid sessions…

The moment you have to look up the user object, you've lost the primary advantage of JWT, and might as well ditch it.

It depends how you store and look things up. There are so many optimization opportunities and strategies to make the lookups fast that this is pretty much a non-issue in practice (e.g. deny list implemented as any combination of runtime or in-memory index, trie, or bloom filter). At the first invalid bit the lookup fails and the token is allowed to proceed to subsequent auth checks. Which should happen quickly for the vast majority. No need to head straight for the worst possible implementations, like whitelist disk lookups.

Re: Stop Using JWTs

#167
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…

What do you do about availability? AFAIK the choice is to pick one of 3 or 4 hacky difficult-to-administer clustering solutions, or have that single PostgreSQL database be a SPOF for your whole system.

Re: Stop Using JWTs

#169
post #107

Earlier quoted context omitted.

WTF: > Each user has a secret: Stored securely in the database. > Stateless Validation: The core validation remains stateless. We only need to consult the database for the user's secret, which we'd likely do anyway for authorization checks. Is "stateless" the same as "serverless" now? Is author's brain stateless?

A JWT is usually signed, with a secret you keep in your app. The statelessness of JWT is that it contains all the information you need to verify it. You do not need to ask a db if the token is there and valid. Storing a user's secret, the same way you store your applications secret does not make it more or less stateless. In since you now have 2 layers of protection, you don't actually need to verify agains a user's…

> [...] you don't actually need to verify agains a user's secret immediately, you simply need to check that the token is valid using the app secret. The subset of valid tokens that you need to check is much smaller than the universe of all the unexpired tokens your application has issued.

What you are describing here is different than what is described in the blog post that you linked to.

Please look at the definition of the function 'validateToken'. In particular, notice how 'getUser' function (which the author notes issues a DB query) is called for every JWT with a valid signature!

EDIT: I failed to realize that you are the author of the blog post. Still my point stands, in that your description doesn't match what the code does.

Re: Stop Using JWTs

#170
post #107

Earlier quoted context omitted.

WTF: > Each user has a secret: Stored securely in the database. > Stateless Validation: The core validation remains stateless. We only need to consult the database for the user's secret, which we'd likely do anyway for authorization checks. Is "stateless" the same as "serverless" now? Is author's brain stateless?

A JWT is usually signed, with a secret you keep in your app. The statelessness of JWT is that it contains all the information you need to verify it. You do not need to ask a db if the token is there and valid. Storing a user's secret, the same way you store your applications secret does not make it more or less stateless. In since you now have 2 layers of protection, you don't actually need to verify agains a user's…

> Common workarounds like maintaining a blacklist of revoked tokens introduce statefulness, negating the benefits of JWTs.

> Validation: On each request, we validate the JWT's signature using the application secret and then validate the sjti using the user's secret.

Having to lookup the user secret from the db is no different than consulting a list of revoked tokens. You claim consulting a list of revoked tokens to be stateful. How is looking up the user secret different?

Post reply on HN