A JWT has all the information for verifying its own lifetime contained within it, which is cool in that you don’t need to hit the DB to verify it… until you want to invalidate it before the embedded expiration is hit.
Then you need to hit the database or some cache layer to verify that it isn’t invalidated, and now one of the biggest reasons to use it is gone.
They do mention that for CRUD operations you’ll need to hit the DB anyways, which is in the same vein as this issue tho.
A perfect example is when SPA's were created, but it broke browser history. So we get a new standard with the ability to edit browser history.
I feel like refresh/access tokens fall into the same vein. If you need that don't use JWT's. The choice of JWT is the problem here, refresh/access tokens are a workaround.
I wrote it up in another comment, but basically: if you're using JWTs, and you have lots of services calling each other in a request (as you might with microservices), it's entirely appropriate to have a session check ("remote introspection") when you access sensitive information, such as PII.
And, maybe, at the edge layer as well.
It’s not terribly difficult to do because most JWTs should only last 10 to 15 minutes. We just broadcast the “jti” of the blocked JWT along with its expiration. The recipients just hold it in memory for that duration. That’s a relatively compact message so it’s quite simple to hold for 10 to 15 minutes.
One of you mentioned that it fails open. True but it’s mitigated by the fact that it’s only alive for 10 to 15 minutes (which you can still do a lot of damage with depending on scenario) and we repeat the message over a few times. In our case, it’s just being extra cautious since we’ve never seen our message bus fail. And if it does, functionality is impaired anyways for many of our services so it also inconveniences the attacker too. Maybe your scenario is different but in our case, it’s more than good enough. The attacker has to line up multiple holes to even get to this point. Or put differently, if an attacker is going to succeed in penetrating, it won’t be because we failed to receive a log out message from our message bus after someone has already logged out but before the JWT expired.
There are systems at scales where you have to take that hit, but the overwhelming majority of people don't run them.
Companies not capable of doing this properly have bigger issues that Paseto won't fix either. Such companies would do well to use products/frameworks based on standards implemented by people that do know what they are doing. And mostly those would rely on JWTs.
That's the whole problem. The majority of the time I've seen of JWTs, they weren't "used properly".
Hm
> PHP becomes the first programming language with modern cryptography in its standard library thanks to the bundled libsodium
https://www.jetbrains.com/lp/php-25/#e_2017_11_30_2
If the snarky comment is aimed at the developer posting the claim, yet again, wrong target.
Don't be like that please.
local introspection: validating the validity and lifespan of a jwt by checking it cryptographically. does not need to make a network call, thus very fast and a great way to perform a low stakes operation.
remote introspection: validating the integrity and lifespan of a jwt by checking with the server that signed it and/or the server that issued the session. this should happen at least once per call flow, ideally as few times as possible but also every time sensitive information is accessed
if you have a heavy call graph, you can do local introspection on everything in the middle. and then, when you go to retrieve pii, do remote introspection.
if your token is appropriately short-lived (15 minutes), this means that an attacker can only yield information within that window with token scraping. that means that an attacker can only access data for as long as they have a foothold. i hope you have strong reporting and immutable architecture :)
> If you’re building a simple website like the ones described above, then your best bet is to stick with boring, simple, and secure server side sessions. Instead of storing a user ID inside of a JWT, then storing a JWT inside of a cookie: just store the user ID directly inside of the cookie and be done with it.
so basically, if your application is doing its own authn/authz (most monolithic applications), you don't need jwts.
That's what session id (as mentioned in the article) is for.
- Multi-Factor Authentication Sucks
- Nobody Cares About OAuth or OpenID Connect
- What Happens If Your JWT Is Stolen?
- Why JWTs Suck as Session Tokens
I would rather write an article titled: Why all those blog posts suck
From what you've written, I'd safely bet your attention span is really low and that you haven't read a single one of those before writing the comment here.
I am neutral to this conversation but thought you might not want to justify this point as it is against the spirit of HN. Specifically in the guidelines:
> Otherwise please use the original title, unless it is misleading or linkbait; don't editorialize.
Which would give the submitter permission to change the title to something more substantive.
> If you’re building any type of service where you need three or more parties involved in a request, JWTs can also be useful. In this case the requesting party will have a token to prove their identity, and can forward it to the third (or 4th … nth) service without needing to incur a real-time validation each and every time.
But it doesn't seem like a good idea to expose the JWTs to the user directly: what if a user updates their phone number? This won't be reflected in already generated JWTs. It seems like a better idea to, at the frontend, generate any JWTs you need to pass to backends and use those to avoid fan-in to whatever identity service, rather than handing those JWTs directly to the client.
(1) Size Factoring Gzip and HTTP/2 header compression into this, size is no longer an issue, but it's still a reasonably good idea to keep claim sizes down. If you don't like using cookies, use a sessionStorage value and affix via XHR! Easy
(2) You're Going to Hit The Database Anyway No you aren't, necessarily? Wth. Also, JWKS paired with JWT gives fantastic rotation security with very minimal configuration across systems. So, maybe you don't even have the database accessible to you. You can still verify your signatures.
(3) Redundant Signing Sounds like this is advice for some framework that signs the session cookie? This is silly.
"You should use Session IDs instead"
Tell me you haven't built a globally distributed system without telling me you haven't built a globally distributed system.
If I use JWT I get widely battle tested library support and near-universal acceptance among developers, which is more than enough for most of the folks to go with JWT IMHO.
You couldn’t drag me back to server side state management for anything.
OAuth2 and JWT tokens is one of best inventions and has proven itself quite thoroughly.
This article was goofy in 2017 and it’s even goofier now.
Determine ttl by considering the context and then balancing performance/security concerns.
If you need to invalidate a session before the ttl expires, throw the identifier in a memory cache. But I think this is overkill for most applications. Rather, protect important state changes by asking user to enter password or to provide other form of auth.
If the frontend wants access to the jwt data, a pattern I like is splitting the jwt by keeping the header and payload in js readable cookie or local storage, then keep the signature in an http only cookie.
[0]: https://securitycryptographywhatever.buzzsprout.com/1822302/...
That info wouldn’t be in the session db row either.
>> “ A database write needs to occur to persist information (if this information is related to the user, it’s likely that the full user object must also be retrieved from the database”
This type of info doesn’t get updated frequently. Email, phone, name, etc, are pretty static. If they are just talking about a join using a userId, well that’s not gonna be any different whether you know the ID from a JWT or normal cookie.
>> “ The full user object must be pulled out of the cache / database so that the website can properly generate its dynamic page content”
But that’s an upside of keeping more than a cookie with an ID. You can just stash the stuff that doesn’t change much client side (keeping in mind the XSS risks). We certainly don’t pull the user’s email and name every page load even though it’s displayed on every page.
>> “ Almost every web framework loads the user on every incoming request. This includes frameworks like Django, Rails, Express.js”
That’s a framework issue and should be customizable. Not really a JWT vs cookie w/ ID topic
There’s plenty of reasons to choose an ID cookie vs a JWT but the many that the author gives are not among them.
It's basically just signed authentication material
Use it when you need to keep your authentication layer horizontally scalable & stateless
Use it when you're transferring trust to an untrusted system, acting on behalf of a user (SAML, OAuth, OIDC)
that's it
It's just signed material
data size limitation (from the blog) is a big meme (source: me). Just pack it into a protobuf lmao
eventual consistency of a stateful session will hurt you btw
yes yes yes I know. The grey bears gave us protocols, rfcs, etc. MUH PROTOCOLS. just give me a private key and a bud light dude
the protocols are important for oidc/oath/saml
JWT ISN"T A PROTOCOL
i'm tired, I should go sleep
Someone missed the entire point of audience claims in OIDC - on okta.com no less.
Nobody was ever fired for using JWT for authentication.
I haven't seen it much discussed, and seems to solve a lot of issues from JWT