Live data from Hacker News

Stop Using JWTs

gist.github.com

241–250 of 335 posts

Re: Stop Using JWTs

#241

Earlier quoted context omitted.

The people who are upset about JWTs probably got burned by trying to use them in a weird way. Some people try to store sensitive data inside JWTs... WTF, the idea would never have entered my mind! Sensitive data should stay on your server. Encrypted or not! JWTs are supposed to be signed, not encrypted! You shouldn't even think to put sensitive info in there. Also, WTF is wrong with people who accepted algorithm "non…

> Also, WTF is wrong with people who accepted algorithm "none." They dared to use the default validation function of their JWT library. They did not choose to accept "none". And the library authors implemented it because it's in the spec. It doesn't excuse that the default was to accept "none", but it is an explanation and in my opinion a valid critique of the standard.

You could have a SQL library that defaults to inserting "OR 1=1" to every update query, which the SQL standard allows. I would blame the library.

Re: Stop Using JWTs

#242
This is stupid/dangerous advice and I will die on this hill.

> The JWT specification is specifically designed only for very short-live tokens (~5 minute or less). Sessions need to have longer lifespans than that.

Your auth token should be 5 or 10 minutes long, yes. Your session should be encoded in a refresh token, which can be another JWT or completely opaque, whichever you prefer.

> "stateless" authentication simply is not feasible in a secure way. You must have some state to handle tokens securely, and if you must have a data store, it's better to just store all the data. Most of this article and the followup it links to describes the specific issues:

No. Stateless auth is completely feasible in a secure fashion. You need short lived tokens as stated above, and to perform instant logout you need to be able to identify JWTs that were invalidated at the level of your API gateway. You don't need to store every JWT that is valid, only a way to identify the ones you want to invalidate early. If you make bulk invalidations not go onto this store (and just accept that with bulk logout, users will remain logged in for up to 5 minutes, which if you're doing logouts in bulk, this does not matter to begin with), then this typically fits in memory. "if you must have a data store, it's better to just store all the data" is just wrong.

And of course for refreshing the token, you go to your data store and recompute things. But the point is to do this every 5-10 minutes like the author (correctly) identified, not on every API request.

> JWTs which just store a simple session token are inefficient and less flexible than a regular session cookie, and don't gain you any advantage.

But no one does this. People use JWTs as auth tokens which are short lived but contain a bunch of information about the users that you'd get in huge trouble if it could be forged (user ids, resolved geolocation, entitlements, cohorts, etc etc), but that you also don't want to make every service of yours look up against a data store or compute for every single API request. It should be data that normally doesn't change during the duration of the auth token. When it does change, you should have a mechanism to immediately invalidate the previous one (see above) and issue a new one on the API call that made the change. Simple.

> The JWT specification itself is not trusted by security experts. This should preclude all usage of them for anything related to security and authentication. The original spec specifically made it possible to create fake tokens, and is likely to contain other mistakes. This article delves deeper into the problems with the JWT (family) specification.

Yes, all standards are horrible if you look at them long enough. XML is terrible, YAML is terrible, ASN.1 is horrific. I'll take a flawed standard that has been studied and criticized publicly so I have libraries and know where the footguns are vs rolling everything myself and having to find out the footguns on my own.

Re: Stop Using JWTs

#243

I'm right now adding rabbitmq for notification pushing to a website. Using JWT authentication to control where and what clients are allowed to read, with short lifetimes and regular token refresh. I don't see another setup that comes close to the ease of setting this up - add an endpoint that provides jwt tokens to valid sessions, done. With user-individual permissions.

Completely, for some things it’s okay to trust the JWT. Nobody is saying let people transfer money or view government secrets with only a JWT and no security in depth. However receiving and potentially sending ephemeral communications seems fine, nobody got hurt in the 30mins the stolen token was valid for!

Re: Stop Using JWTs

#244
post #47

Earlier quoted context omitted.

Fair enough, but those optimizations are basically free. People think stateless tokens are free but they really are not.

> Fair enough, but those optimizations are basically free. People think stateless tokens are free but they really are not. Strawman. The only requirement for a JWT is posting the JSON Web Key set with the public keys used to verify the JWTs signature. That's the full cost of a no-frills JWT implementation of you exclude IAM. If you want to have one-time JWTs you need to maintain a revocation list. This is literally a…

Yes we have heard this before, React is only 30kb! But that misses the enormous amount of infra you need to even just do a basic fetch. (Read the post by the React Query author on whether you need React Query or not)

Likewise with JWTs for sessions you need to handle cache invalidation, revocation lists, key rotation, the list of difficult comp sci problems really does go on!

The same issue as always plaguing the frontend world. Up front “simplicity”, enormous actual complexity

Re: Stop Using JWTs

#245
There isn't any point in the article or video that describes why it is worse than session token in any way. Personally, I think 5 minute expiry is too long and I think 10-30s expiry is the ideal range, so that one page load requires 1 token.

> Sessions need to have longer lifespans than that.

Why is this JWT issue. JWTs generally have refresh token, which are database validated and we need to just refresh once for 100s of calls in 5 minute.

> "stateless"

Yeah this sounds bad and I don't think people do it.

> JWTs which just store a simple session token are inefficient and less flexible than a regular session cookie, and don't gain you any advantage.

Ok, but it is not worse too.

> The JWT specification itself is not trusted by security experts. This should preclude all usage of them for anything related to security and authentication. The original spec specifically made it possible to create fake tokens, and is likely to contain other mistakes. This article delves deeper into the problems with the JWT (family) specification.

What are they even trying to say?

Re: Stop Using JWTs

#246

This is stupid/dangerous advice and I will die on this hill. > The JWT specification is specifically designed only for very short-live tokens (~5 minute or less). Sessions need to have longer lifespans than that. Your auth token should be 5 or 10 minutes long, yes. Your session should be encoded in a refresh token, which can be another JWT or completely opaque, whichever you prefer. > "stateless" authentication simpl…

This does not address how much the JWT header is a security footgun (eg you can inline remote keys into the header). if you are doing something simple you can disable all "advanced" features and be pretty safe but if you are doing something a bit more complex it is not so easy.

The only case where JWTs are actually useful is when the producer and consumer do not share a DB (eg OAuth/OIDC, iot deployments, heavy microservice architectures) otherwise a good cached session store should handle well up to a few orders or magnitude below google scale.

Re: Stop Using JWTs

#247

Earlier quoted context omitted.

Spec writers and library authors are human? Who knew

PASETO and TLS 1.3 were also written by humans. TLS libraries (which are several orders of magnitude more complicated than JWT libraries) are also written by humans. If you passionately care about security and misuse-resistance you CAN write a spec that will lead to fewer implementation issues.

You must be young if you're pointing to TLS libraries as an example of doing it right and not getting into trouble with insecure implementations and downgrade attacks. https://wiki.freebsd.org/LibreSSL

Re: Stop Using JWTs

#248

I'm sorry I fail to see the difference between a cookie holding a server session ID and a cookie holding a JWT token. JWT sessions are created and stored (in some way) in the DB anyway and it's short lived. That's basically a session stored in a DB. When we say no to sessions we only mean server sessions in your backend service as this can't scale horizontally. I feel like this is just a shiny title confusing differe…

JWTs aren't stored in a backend though.

Session cookies you exchange an opaque value with the DB for the user info

JWTs the user hands you their driver's license, and you can verify that it's an authentic license for the person who's name is on it

Re: Stop Using JWTs

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

We have a single harbor instance at work, backed by PG. The folks ran into some sort of performance issue during their testing (not documented) and their solution was to use cloud native pg, run two postgres, and add additional second layer of connection pooling.

We eventually hit a bug in a combination of certain images, docker desktop (not even supported by us), and permissions. The error looked related to the connections, so I suggested the pooler be bypassed as a test. They ignored the suggestion for two weeks until it was the last thing to test.

Sure enough bypassing the pooler helped stabilize the connection from harbor during image uploads.

Now I need to talk to them about properly vertical scaling PG before we try and run two with replication, in the same kube cluster, in the same physical data center.

Re: Stop Using JWTs

#250

Earlier quoted context omitted.

API tokens are a very small narrow part of the authorization universe. Having a shared secret relies on a trust relationship between the resource server and the identity provider that does not exist between, say, my SaaS backend and Google or Meta's login system.

The OP was talking about sessions (which include session cookies and API tokens). I'd argue these use cases are far more common for the average programmer than tokens and signatures that are used for federation, but I'll bite the bullet here: JWT is a serviceable solution for service trust and federation. This use case often just requires a very-short-term token, so lack of revocation support is not an issue. Replay…

> If you do use the authorization code flow securely (on the server side, with a strong client secret and proper CSRF protection)

This restriction precludes all desktop clients, mobile clients, and webapp clients -- any place where you can't trust the client code to protect a secret.

I don't exactly disagree with you: Security becomes much easier once you rule out handling all the hard edge cases.

Post reply on HN