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 evidence than just one blog post. And that blog post seems to just largely blame bad implementations? Something that will plague any standard.

Overall, I don't know what I expected clicking a random gist link.

Yeah... some early implementations just allowed for any authority to be set in the header and trusted it... that's of course wrong from the start... if you only allow for trusted or "known" authorities a lot of the contextual concerns become non-concerns.

Beyond this, you can make shorter lived JWTs just fine in the browser and have the agents self-update. If you use Azure Entra or a number of other providers it works this way in practice... you keep your JWTs relatively short lived (5-15m) and can even check for jti revokation.

JWTs are incredibly useful for separating/reusing an access authority from your applications/api systems. You shift the attack surface and do it in a way that can be trusted. We use PPK for lots of things, including SSH all over the world. No, I wouldn't use shared secrets and I wouldn't use long lived tokens... but short lived, ppk signed tokens from verified/known sources are generally fine.

For that matter, it's often API keys that are really problematic. Just had to implement them... for me, the API key presents as a Bearer token as well, but there's a short "sak." prefix then an identity part (base64url uuid bytes) followed by a secret as base64url bytes... in the database is the uuid and a passphrase level salt+hash from the secret.. so the api key generated should be treated as a secret and is one-way to the database, so a db breach doesn't breach auth.

Even then, an API key leak is far mroe likely than a problem with a well implemented JWT solution.

Also many situations just don't require a "Logout" button and hence don't require a revoked list.

On a linked page, there's also this:

> Any JavaScript code on your page can access local storage: it has no data protection whatsoever. This is the big one for security reasons (as well as my number one pet peeve in recent years).

This is a weak argument. You know, just don't put "any javascript code" on your webpage? Limit it to trusted javascript code? If you allow random people putting random javascript on your webpage, you have already lost anyway!

The author made a good point here about running trackers and ad ops (think Google analytics or ad words). I'd guess if you don't run those, it'd just be supply chain attacks that could exfiltrate secrets.

This seems like one of those scenarios where you make different trade offs depending on your threat model. The author's threat model sounds similar to a news site where they track and advertise so they're forced to run semi-trusted js.

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.

So don't do that - and you're stateless!

I can't recall the last time I used a "Logout" button anywhere. I no longer visit internet caffees...

Logout functionality is not the only use case for token invalidation. Another significant one is to revoke a token that has been exposed, like inadvertently pushed to GitHub. In that case you want to invalidate the token to a avoid unauthorized access to your service.

With vanilla JWTs, you have no way to do this! But then if you add revocation checking on top (which people do), your JWTs are no longer stateless.

Every authentication system i ever implemented (and I worked on many) needed some way to invalidate sessions regardless whether it’s self service for the user or not.

And once you do you need some state and then JWTs don’t make much sense anymore. There are of course many valid use cases for JWT so “JWT bad” is a very reductive take

It's curious: very few authentication systems I ever implemented needed some way to invalidate sessions.

You either reissue tokens constantly, every couple minutes or so, or you have to reliably invalidate.

Maybe you do. Why would I have to do that?

Because it's bad to ship products where a compromised token can never be recovered from. Revocation is the essential hard problem in authentication/authorization.

How can you provide a stateless logout (that invalidates credentials rather than simply forgetting them client side)?

> "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.

100% agree. This is common sense to me and I'm always surprised to re-learn people don't do this

Not checking the signature on every single JWT is the same as storing a password in plain text.

worse, it's storing identities in an editable format that any attacker can use to impersonate any user, no?

Even worse than both of those scenarios. If you don't check the signature anyone can simply write whatever they want in the payload string. The signature is always generated by combining the payload with a private key. Then the receiver uses the public key to verify the signature. If you don't do that the payload can be modified to be anything. Storage not required by the attacker.

It's like prompting for a password but accepting any password as valid.