News for hackers. Stuff that matters.
Re:JWT should not be your default for sessions by rsj_hn on Wednesday May 12, 2021 @08:36PM (#27137010)
JWTs are good for API tokens, not end users. If you use JWTs for your cookies/session state, then you'll still need to maintain a table of valid JWTs and expire them when the user logs out, and thus you will not be able to use JWTs as they were intended to be used, which is as stateless tokens.

Most security auditors/certifications/compliance requirements do not consider even a 5 minute lag acceptable for user driven logout. The definition of logout is that when the user presses the logout button, all the session data is invalidated server-side during roughly the time it takes for a request/response roundtrip.

Thus there is no benefit to using a non-opaque high entropy string for user sessions, even though there is a good benefit to using JWTs as API tokens for back-end services (esp. microservices) that do not have browser logout requirements.

Re:JWT should not be your default for sessions by lmm on Wednesday May 12, 2021 @09:40PM (#27137488)
I've seen plenty of people make the equal and opposite wasteful mistake: they insist on using a shared state store so that logins can be properly revoked, then they notice that every server looking up the session in this shared store on every request is having a significant performance impact, so instead they have the server cache sessions locally for 5 minutes (or even longer).
Re:JWT should not be your default for sessions by spookthesunset on Wednesday May 12, 2021 @11:10PM (#27138009)
That is the cool thing about JWT. You get the best of both worlds. With JWT you don't have to hit the auth server for requests where a ~5 minute (or whatever) window doesn't matter. That is probably 99% of the authenticated traffic on a lot of sites (thinking of HN, reddit, youtube, etc). On requests that matter, like on a write request or a "sensitive" read request, you can always ping your auth server to make sure the token is still legit.

Cutting out 99% of your auth backend traffic can dramatically change how you design it.

Re:JWT should not be your default for sessions by ravenstine on Wednesday May 12, 2021 @11:42PM (#27138139)
This seems like an invented problem.

What is an auth server fundamentally?

It's a hash table lookup.

Which happens to be something that computers are designed to be really good at. I've never worked at a company where auth or storing user sessions was a bottleneck.

Re:JWT should not be your default for sessions by spookthesunset on Wednesday May 12, 2021 @11:49PM (#27138171)
I worked at a place whose auth server system literally serviced tens of billions of request per day. 99% of that traffic was for "dude was logged in and is looking at some page that is not unlike the one you are reading right now on HN". JWT let us cut that traffic by 99%. The remaining 1% was for servicing refresh tokens and handling requests for "sensitive" traffic (i.e. account page, anything involving writes, anything dealing with billing). This was in a system with data centers across the globe.

Auth might not be your primary bottleneck, but each page load you service has a latency budget and every millisecond spent being blocked on some auth call is a millisecond that could be spent doing else. And trust me, your database or crazy "solve it with redis" server isn't responding in 1ms, it's gonna be at least 20ms due to network overhead and the variance in latency on that request isn't always "20ms" it is "99% of the requests are 20ms and 1% are >>100ms". So now 1% of 10 billion requests (100 million requests) take way longer than 100ms... well that sucks...

Not to mention when your auth backend blows up and dies... your site is completely dead in the water. JWT can at least let you tread water for a while.

JWT is amazing. People that diss it don't understand it, or likely don't understand the tradeoffs they implicitly made with their own auth architecture.

Re:JWT should not be your default for sessions by user5994461 on Thursday May 13, 2021 @03:55PM (#27146584)
>>> I've never worked at a company where auth or storing user sessions was a bottleneck.

I can tell you from my experience working at JP Morgan (the largest US bank) that authentication checks was the #1 root cause of major outages.

That is, except when it was #2. It was a close tie with network related issues depending on the season.

It's easy enough to understand that when sessions can't be checked, every application and service that need to check sessions are effectively 100% down.

Another hard learned fact is that (very) critical services or (very) high traffic services will simply never support remote sessions, because it's too slow and unreliable. (There are potential alternatives like JWT tokens or TLS authentication).

Re:JWT should not be your default for sessions by ledauphin on Thursday May 13, 2021 @12:29AM (#27138418)
it's not the hash table lookup that is expensive, it's the network request.

Computers are not good at network requests because physics says they can't be - it takes orders of magnitude more time for light/electricity to traverse even one side of a datacenter to another than it does to go from the CPU side of the motherboard to the RAM side.

For plenty of use cases, the additional network roundtrip is very affordable. But it's simple math that explains why this might easily become half or more than half of the total load on your systems if you want to "just do an additional (network-mediated) hash table lookup" on every request.

Re:JWT should not be your default for sessions by sneak on Thursday May 13, 2021 @02:31AM (#27139095)
The 100-2000ns it takes signals to move across a datacenter and back is not the primary cause of a network request being slow in comparison with a cpu.
Re:JWT should not be your default for sessions by spookthesunset on Thursday May 13, 2021 @02:35AM (#27139114)
LOL to 2000ns. Seriously?

10ms minimum to go to the next rack. For 99% of the requests. For the unlucky 1% you'll get outlier performance due to.... well... you spend the next sprint figuring it out and the next quarter trying to solve that scaling bottleneck.... It could be network, it could be some weird design thing, it could be redis, who knows? But yeah... enjoy figuring it out instead of focusing on your product.

1% of all requests is actually a lot of requests. And if you think 1% of your auth requests aren't 10x the median... you aren't measuring it hard enough.

Re:JWT should not be your default for sessions by brobinson on Thursday May 13, 2021 @02:51AM (#27139187)
What on earth kind of clownish network setup do you have where O(1) lookups over a network take 10ms? I worked on a tiny (3 people) engineering team serving 250,000 http requests/second 27/7/365 doing 5-6 over-the-network requests to other services (memcached, redis) per request we handled and our 99th percentile time to get a response on the wire was < 15 milliseconds.
Re:JWT should not be your default for sessions by brobinson on Thursday May 13, 2021 @03:17PM (#27146157)
"24"/7/365... we weren't warping spacetime to get responses on the wire that fast.
Re:JWT should not be your default for sessions by sneak on Thursday May 13, 2021 @03:04AM (#27139253)
That's exactly my point, you are agreeing with me. I was refuting the comment claiming that networks were slow compared to on-die comms because of physics and lightspeed.

The signals going through the wire and back are 2000ns in a big datacenter. There are orders of magnitude more delays in the processing of those bits than their transmission through space via twisted pair or fiber.

It's not 10ms to go to the next rack though unless your network is broken. You're much closer to 100us (100,000ns).

Re:JWT should not be your default for sessions by imtringued on Thursday May 13, 2021 @11:50AM (#27143481)
Yes, it takes 2000ns for the signal to travel at the speed of light. ledauphin never talked about the time spent processing the signals, which is incredibly odd because that's where most of the time is being wasted.

This is a very common pattern in networking, people underestimate the speed of light and overestimate the speed of network equipment.

Re:JWT should not be your default for sessions by lamontcg on Wednesday May 12, 2021 @11:46PM (#27138158)
On the front end you also have a user id in plaintext that you can use for request routing to send the user to the right shard in the right datacenter. That doesn't have to be cryptographically secure since cryptographic auth happens in a later step. By not having to decrypt anything your front end geographical load balancers can handle higher bandwidths (and more headroom for DDoS attacks).
Re:JWT should not be your default for sessions by LanceH on Wednesday May 12, 2021 @11:48PM (#27138167)
This is optimizing for an already solved problem in a way that adds complexity and increases the opportunity for security problems.
Re:JWT should not be your default for sessions by spookthesunset on Wednesday May 12, 2021 @11:53PM (#27138199)
JWT solves all kinds of problems, you just haven't encountered them or aren't sophisticated enough to detect them yet. I'd assert that all the solutions you might propose have their own non-trivial issues.

For example your auth server better be god damn awesome if it is gonna service every front-end page load. If even 1% of its traffic takes an order of magnitude longer than the median... that means 1% of your front-end traffic is gonna take an order of magnitude longer too. Lord help you if that fucker hiccups for a minute every so often... JWT shields most front-traffic from auth-server latency issues because most front-end traffic never needs to talk to the backend. (And no, your auth server isn't perfectly designed and yes 1% of its traffic will be an order of magnitude slower for whatever random reason)

Re:JWT should not be your default for sessions by lbriner on Thursday May 13, 2021 @03:21AM (#27139333)
You are arguing against a false assumption.

Most web apps that use "normal" auth don't call an auth service. They drop an encrypted auth cookie that is checked on every page load and which is very fast. Session data and any centralised auth check (banned user for example) are simply database calls, which are no slower than the perhaps 10 or 20 other calls you are probably already making on your page.

> or aren't sophisticated enough to detect them yet

I'm sophisticated enough thanks!

Re:JWT should not be your default for sessions by neurostimulant on Thursday May 13, 2021 @10:11AM (#27142282)
> Session data and any centralised auth check (banned user for example) are simply database calls

JWT doesn't make sense if your app can simply make a direct database calls for authentication check. But if your app is composed of myriad of microservices which aren't allowed to query the database directly and must call another service to access data outside the caller's scope, then yeah the only option is making the authentication service fast enough to tank all the authentication checks or use jwt which makes any microservice able to confirm authentication status without querying the auntentication service.

Which is another reason why I think microservice architecture is a giant waste of time and productivity unless you're google-scale.

Re:JWT should not be your default for sessions by lmm on Thursday May 13, 2021 @03:40AM (#27139429)
> Session data and any centralised auth check (banned user for example) are simply database calls, which are no slower than the perhaps 10 or 20 other calls you are probably already making on your page.

They're calls that you have to complete before you can start making any of the others (since it's not safe to start making database calls based on a user that hasn't been authenticated/checked for bannedness yet), so you're talking about more or less doubling or tripling your page's load time (check authentication, check authorization, then do the queries that give you the actual data) if you've got decently written queries.

Re:JWT should not be your default for sessions by LanceH on Saturday May 15, 2021 @11:39PM (#27171006)
> doubling or tripling

That's not even arguing in good faith, or shows an extreme lack of experience. Auth/auth is routinely cached. Even if it's a database call, the query used there will likely be cached. Auth is a miniscule portion of a web page's performance.

Re:JWT should not be your default for sessions by lmm on Tuesday May 18, 2021 @01:15AM (#27191469)
> Auth/auth is routinely cached.

Which completely undermines the argument for not using JWT. "We can't use JWT because then tokens would be valid for 5 minutes after the user logged out" - but if you're caching your auth for 5 minutes then you have exactly the same risks.

Re:JWT should not be your default for sessions by arkadiyt on Wednesday May 12, 2021 @08:49PM (#27137131)
They're not even good for API tokens. There are valid use cases for storing data in a signed client-side token, but if you're going to do that then don't choose JWT as your serialization format - there have been too many alg:none or other issues. Just do hmac-sha256(data, secret) instead.
Re:JWT should not be your default for sessions by derefr on Wednesday May 12, 2021 @09:21PM (#27137378)
Middleware like Nginx (at least the Nginx Plus version) know how to take apart JWTs and use the stuff inside. The same can't be said for your arbitrary custom serialization format.

The real use of JWTs is when you want third parties to be able to sign their own API requests, that your API will accept using the very same machinery by which it accepts your first-party-client API requests. If you use JWT, you can just pass the third party a private JWT signing key to use, add the corresponding public key to your validation set for JWT decode on your backend, and everything "just works."

Re:JWT should not be your default for sessions by IgorPartola on Wednesday May 12, 2021 @10:24PM (#27137746)
That seems like a really specific use case. Under what circumstances would you want to do this?
Re:JWT should not be your default for sessions by derefr on Wednesday May 12, 2021 @10:46PM (#27137877)
A better use-case is having a third-party upstream service that you want your own service's users to be able to talk to directly — i.e. without using your service as an intermediary gateway. If you configure your third-party SaaS with your own JWT public key, you will be able to have your users

1. Log in with your service, receiving a JWT token

2. Send that token back to your service, as the auth key for authenticating as themselves with your service.

3. Also send that same token to the third party service, to authenticate requests against your service's account.

(One place where I just set this up the other day: allowing users of a crypto app to make authenticated requests to Infura via the MetaMask browser extension, where we're paying for the Infura credits to enable that. We send the user a JWT token; the client JS uses that token to build an Infura URL, and configures the MetaMask SDK with it. Infura accepts the requests as coming from "us" because it recognizes the JWT signing key we configured.)

Re:JWT should not be your default for sessions by hrktb on Thursday May 13, 2021 @01:48AM (#27138858)
We hit this case with a customer service where each “domain” (transaction management, fidelity, auth, catalog data, etc.) was handled by a different internal org, with an orchestrating layer on top.

Having the emitting entity sign their request in a standard format that can be checked by anything having with their public key helped a lot.

Re:JWT should not be your default for sessions by lbriner on Thursday May 13, 2021 @03:23AM (#27139346)
Most web frameworks support JWT out of the box so just calling a web service written in these means it is preferable to use an existing format rather than rolling your own.

Sure there are some gotchas but it isn't that hard to read up on that once, configure your JWT check and then leave it alone.

Also, we pass additional claims in the JWT that avoids the need for the web service having to check certain permissions or auth status itself (like what resources the user has requested) and this is going to be a mess if you try and "just HMAC(SHA256())"

Re:JWT should not be your default for sessions by genghisjahn on Wednesday May 12, 2021 @10:32PM (#27137798)
Or use rsa for the token signing. 3rd party keeps the private. They send you the public. You can verify all the tokens. They are the only ones that can create new ones.
Re:JWT should not be your default for sessions by derefr on Wednesday May 12, 2021 @10:39PM (#27137839)
Yes; that is, in fact, how JWT works.

The point of JWT is that it's an ecosystem of stuff that all has built-in support for doing this. You don't have to arrange for this kind of signing "by hand"; on most services that have JWT "accept" support, there's a portal with a configuration field where you can just paste in a public key. Same as adding a line to ~/.ssh/authorized_keys, but for web requests.

(Yes, all of this is just a bad imitation of TLS client certificates. But browsers have a horrible, intrusive, non-syncing UX for client certificates. If they did with client certs what they do with cookies/passwords, nobody would have bothered to invent JWTs.)

Re:JWT should not be your default for sessions by BelenusMordred on Thursday May 13, 2021 @01:08AM (#27138631)
> Just do hmac-sha256(data, secret) instead

Or use SHA3(secret || data), it was specifically designed to not have the pitfalls of sha2 which made HMAC constructions necessary along with being less computationally expensive. There's also KMAC built from keccak which has some advantages over simply hashing the concatenated key and message.

https://csrc.nist.gov/publications/detail/sp/800-185/final

https://crypto.stackexchange.com/questions/17735/is-hmac-nee...

Re:JWT should not be your default for sessions by josephg on Thursday May 13, 2021 @01:53AM (#27138892)
A friendly reminder for the 99% of people here who, like me, don’t live and breathe this stuff:

Don’t “just” use some crypto construction you read on HN. Don’t invent your own thing. Find a well respected crypto library (eg libsodium) and look up your use case in the API documentation. Eg, for authentication libsodium exposes these API methods:

https://libsodium.gitbook.io/doc/secret-key_cryptography/sec...

Re:JWT should not be your default for sessions by BelenusMordred on Thursday May 13, 2021 @03:54AM (#27139514)
I provided a link to a NIST spec on this exact issue and a stackexchange discussion with lots of eyeballs/votes. Sure, don't just listen to me, but please do listen to them.

Using sha3 as stated above is certainly something to consider for the numerous people out there implementing message authentication into their systems. It's simple and hard to mess up, if I was building a greenfields project today is probably the tool I'd reach for.

Libsodium is fairly complex and had it's own issues. Sha3 implementations in most languages are battle-hardened and simple to use.

Re:JWT should not be your default for sessions by chupasaurus on Thursday May 13, 2021 @02:38AM (#27139128)
That's why Cryptographic Right Answers [0] is a thing.

[0] https://latacora.singles/2018/04/03/cryptographic-right-answ...

Re:JWT should not be your default for sessions by tialaramex on Thursday May 13, 2021 @03:58AM (#27139555)
As that version of the post alludes to (in talking about D-H) the problem is that the people who most need these answers don't know how to ask their question in a suitable way. The NaCl/ Sodium APIs are oriented around applications. You want to do X, Sodium says you should call this API and the things you get back have the following properties.

For example, what Sodium will actually do for the API your parent mentioned is HMAC-SHA512-256 ie it's using SHA512/256. But rather than give that as advice (and risk some developer either trying to re-implement SHA512/256 because their tool doesn't offer it, or worse, thinking SHA512 sounds strictly better so they'll do that) - Sodium just implements the thing you should do.

But if I were going to write a snarky "Right Answers" type post about this subject what it would say is that JWT almost certainly isn't the solution to a problem you have, it might be a solution to a problem you wish you had, but you likely have actual problems, now, and you should work on those.

Why do I say "wish" you had? Well as we see in a lot of these threads, immediately people talk about how it'll be a struggle to scale up the naive session approach when you have this big geographically distributed system. If your startup becomes Facebook or Google, you'll have to rewrite all this stuff. Why not instead use JWTs?

Your startup isn't going to be Facebook or Google. When you prove me wrong you'll have piles of cash for engineers to fix the scaling problems you knew about and, much more importantly, all the other problems you'd never dreamed of. You are attempting premature optimisation.

Re:JWT should not be your default for sessions by Redoubts on Thursday May 13, 2021 @07:50AM (#27141036)
“”” Asymmetric encryption

Percival, 2009: Use RSAES-OAEP with SHA256 and MGF1+SHA256 bzzrt pop ffssssssst exponent 65537. “””

Am I having a stroke?

Re:JWT should not be your default for sessions by rsj_hn on Wednesday May 12, 2021 @09:14PM (#27137319)
yeah, I'm not a fan of JSON or XML signatures, but for some reason developers love them. I've given up on that battle
Re:JWT should not be your default for sessions by lbriner on Thursday May 13, 2021 @03:25AM (#27139355)
Why would you not like a solid mechanism for verifying that a data packet hasn't been tampered with? In the case of JWTs which live in the browser, it would be essential that they are signed.

dotnet auth tokens are also signed, they are stored in cookies, is that any different?

Re:JWT should not be your default for sessions by Rapzid on Wednesday May 12, 2021 @09:07PM (#27137268)
> maintain a table of valid JWTs and expire them when the user logs out

Wouldn't you just need a list of logged-out JWTs? And maintain entries until the JWT would have expired?.

And that's if you really cared. Some people would be fine with the client and server participating in the log out and a low-ish JWT expiry.

Re:JWT should not be your default for sessions by rsj_hn on Wednesday May 12, 2021 @09:17PM (#27137341)
> Wouldn't you just need a list of logged-out JWTs?

Sure, but that's not a real improvement. It's still stateful since you need to check the list with every request, you can't just verify the signature. Changing the logic from "must be in this list" versus "must not be in this list" does not give you much -- maybe some performance gain, depending on the situation.

> And that's if you really cared.

Well, that's my point. Developers may not care, but from the point of view of a security auditor, it's a vulnerability in your auth system, so the GRC/Security people do care, even if Foo start up doesn't. At some point, if Foo is successful, they will face this issue and need to support real logout to get the certifications they need to do business or be in compliance.

Re:JWT should not be your default for sessions by hn_throwaway_99 on Wednesday May 12, 2021 @09:37PM (#27137472)
> Changing the logic from "must be in this list" versus "must not be in this list" does not give you much -- maybe some performance gain, depending on the situation.

As someone who implements this exact solution, it actually gives you a lot. If your JWTs have a relatively small timeout window (say N minutes), then that means the number of expired tokens you have to keep track of is usually very small (e.g. for everyone who clicks the logout button with a valid token you have to keep that token around for at most N minutes), and on many websites the average user never makes an explicit logout request.

So that means that in many (most?) usage scenarios you can just replicate the list of recently expired tokens to your servers (easy with something like Redis) and then just check incoming requests against that in-memory list. Again, this isn't anything special or new, it is discussed in the article.

This is very different from storying the list of every valid JWT, which will often times be much bigger than you can store in memory.

Re:JWT should not be your default for sessions by ecnahc515 on Wednesday May 12, 2021 @09:29PM (#27137427)
JWTs expire, so you only need to maintain a list of invalidated JWTs that haven't expired yet. You get two short cuts, one that you only check for revoked tokens which aren't expired and have valid signatures. This can save a lot of DB queries given you usually have to check auth validity per request.
Re:JWT should not be your default for sessions by lbriner on Thursday May 13, 2021 @03:28AM (#27139370)
How does that help? You won't know which tokens should be considered expired in-advance, you still have to call the DB for every request to check. There won't be many that are called with expired tokens compared with people using the site constantly and always having valid tokens.
Re:JWT should not be your default for sessions by bobthebuilders on Thursday May 13, 2021 @01:48PM (#27145021)
You don't need a DB. The same in memory stuff that supposedly works for fast session auth works here too.
Re:JWT should not be your default for sessions by ecnahc515 on Thursday May 13, 2021 @05:33PM (#27147755)
> You won't know which tokens should be considered expired in-advance, you still have to call the DB for every request to check

You can verify the signature before calling the DB.

Re:JWT should not be your default for sessions by giaour on Thursday May 13, 2021 @06:18PM (#27148197)
You can push a list of revoked tokens to each server (similar to how certificate revocation lists work with (m)TLS).
Re:JWT should not be your default for sessions by Franciscouzo on Wednesday May 12, 2021 @09:51PM (#27137558)
You can use a bloom filter to check if a token has been revoked, and then do the query for false positives.
Re:JWT should not be your default for sessions by xyzzy123 on Thursday May 13, 2021 @12:42AM (#27138492)
Agree, a lot of webapps can just ignore. Suppose you have a 10 min refresh time. Logout just deletes the client-side state and in 10 minutes the user will be "hard" logged out since their token hasn't been refreshed.

Similar security to "abandoned session" which is of course what a very large % of users do instead of "logging out".

There is risk of cloned session, but there's no law saying non-banking apps have to care.

This has the nice property that if you're forced to, adding a cache to store invalidated tokens with a ttl of 10 minutes is an incremental enhancement.

Re:JWT should not be your default for sessions by hobofan on Thursday May 13, 2021 @02:58AM (#27139215)
You can "just" use a per-user "generation" key, which invalidates all keys when incremented server-side. The list can generally be mainted by polling every few seconds or via a websocket if you need the fastest possible expiry. Since most JWT libraries allow you to customize the validation function it's often pretty trivial to add, and overall comes only with a small memory penalty.
Re:JWT should not be your default for sessions by adolph on Wednesday May 12, 2021 @09:41PM (#27137492)
The persisted state of user access can be two of consistent, available and partition tolerant. JWT uses cryptography to expand partition tolerance at the expense of consistency. The lower the requirement for consistency latency in user state, the lower partitions are tolerated, such as geographic availability, multi-rack, multi process and so on down to not allowing client-server partition. JWTs are fine when partitions are more important than consistency and a pragmatic choice to avoid centralized state on a backing service.
Re:JWT should not be your default for sessions by spookthesunset on Wednesday May 12, 2021 @09:17PM (#27137344)
If your environment is such that 5 minutes of lag between logout end a token being invalidated, you can always just verify the token against the auth server per request.

JWT comes in handy for most of your site where it isn’t such a big deal. That way you aren’t flooding your auth server with calls; all your web servers can just validate the token themselves up until a refresh is required.

Basically JWT let’s you have your cake and eat it too. Significantly less load on your auth backend while still letting sensitive parts of the site verify on every request.

Re:JWT should not be your default for sessions by ryan-allen on Wednesday May 12, 2021 @10:22PM (#27137730)
I don't understand why people are down-voting you.
Re:JWT should not be your default for sessions by spookthesunset on Wednesday May 12, 2021 @10:50PM (#27137902)
Because a lot of people see security in terms of black and white instead of a lot of shades of gray. Not everything requiring authentication is your bank account. HN, for example, could have even a 10 minute window and be okay.

Not having to block all your request waiting for the auth backend can improve your latency by a non-trivial amount. It also can make your auth server much less complex.

JWT is awesome. People just think it is "all or nothing" and implement it wrong.

Re:JWT should not be your default for sessions by ryan-allen on Monday May 17, 2021 @03:50AM (#27180988)
> JWT is awesome.

That's generally my thought, too. In my career the authentication sophistication was always a trade off (effort vs security) based on how paranoid the org felt about certain things.

Having worked on PHP/Rails/.NET Webforms/Node.js apis/C# webapis the session management techniques are all very different.

Having run high traffic websites also, the ability to offload logged-in sessions into JWT was really, really nice. Not having to prune auto-generated sessions from disk of PHP applications is a nice thing to not worry about.

Re:JWT should not be your default for sessions by sly010 on Wednesday May 12, 2021 @10:20PM (#27137718)
I am confused. Why can't the client just drop the token and be done with it? Why do you need to store session state on the server to be "secure"?
Re:JWT should not be your default for sessions by wglb on Wednesday May 12, 2021 @10:34PM (#27137806)
Because the server thinks that the session is still alive. The server doesn't know that the client has "dropped" the session. If the dropped token should be somehow be found again, it still has all the authority that the original session did.
Re:JWT should not be your default for sessions by hkai on Wednesday May 12, 2021 @11:22PM (#27138053)
This got flagged by our pentest vendor as well, but to me it sounds like a very unrealistic attack vector.

If one can steal a token from your browser's storage or can intercept your HTTPS connection, then sure, yes, you have a huge vulnerability even without JWT.

Re:JWT should not be your default for sessions by quickthrower2 on Wednesday May 12, 2021 @11:40PM (#27138129)
Could make you less secure if the token was leaked somehow (another vuln for example a cross origin type of thing)

You notice odd behaviour so you log out to stop it but the attacker isn’t logged out.

Also with this setup log out of all devices is not possible! Again something you’d be keen to do if seemingly attacked.

Re:JWT should not be your default for sessions by porker on Thursday May 13, 2021 @02:43AM (#27139157)
I've never got my head round how log out of all devices works. It has to have a central store of all sessions?
Re:JWT should not be your default for sessions by lbriner on Thursday May 13, 2021 @03:31AM (#27139388)
It depends on what auth you are using.

In OpenID Connect, there are back channels that talk to each other so that all devices know you have logged out.

If you are using traditional auth then yes, you would need to track session state against the user so that when they access from a particular device, you could check whether they have already logged out.

Some more complex apps use a background thread to check auth status with the server.

Re:JWT should not be your default for sessions by porker on Thursday May 13, 2021 @08:26AM (#27141306)
Thanks for the insight. As Google has this feature I've wondered how they get it to scale up.
Re:JWT should not be your default for sessions by wglb on Thursday May 13, 2021 @12:16PM (#27143881)
> it sounds like a very unrealistic attack vector.

It isn't unrealistic at all. A lot of attack vectors seem unrealistic to the victim until they happen. How realistic is it to think that a hostile actor can inject their code into a build process without touching the disk, then get that corrupted executable signed; then that signed executable is installed by 18000 users with root permission?

Re:JWT should not be your default for sessions by ryanmarsh on Thursday May 13, 2021 @12:08AM (#27138291)
I’ve only done a few JWT implementations so forgive my ignorance but isn’t this what “exp” and token refreshes are for?

If you don’t want to maintain a centralized session store and you don’t want long lived tokens just set the expiry to 90 seconds. When you attempt a refresh, if the user is logged out it will fail.

I’m really confused by the either/or of “hit central session store on every request” or “tokens that live five minute too long are bad mmmkay”.

Re:JWT should not be your default for sessions by josephg on Thursday May 13, 2021 @02:03AM (#27138938)
Huh? To track if the user is logged in (for longer than 90 seconds) you’ll need another token, used to refresh the JWT token. And you’ll need the normal session infrastructure to validate that anyway.

That sounds like a very complex system to cache session tokens. You may as well just cache normal session tokens for 90 seconds in your application servers. Same result, less complexity.

Re:JWT should not be your default for sessions by IgorPartola on Wednesday May 12, 2021 @10:22PM (#27137731)
I guess because if you have the JWT abs I have your JWT and you hit logout, I can keep using your JWT.
Re:JWT should not be your default for sessions by lbriner on Thursday May 13, 2021 @03:32AM (#27139395)
I think they are saying that to get that JWT would not be easy or likely, since it would need to be used within 5 minutes as well.

Although unlikely, I guess people want to know that clicking logout just does that and that there isn't a chance that some kind of hacker, colleague, nerfarious company or country couldn't continue to use your apps as you.

Re:JWT should not be your default for sessions by stillbourne on Wednesday May 12, 2021 @10:27PM (#27137776)
Because if the client has the token its susceptible to sidejacking
Re:JWT should not be your default for sessions by whateveracct on Wednesday May 12, 2021 @09:56PM (#27137591)
For users, I like to have a secret key per user and put something signed with this key in a cookie to represent the session. Then "log out everywhere" is as simple as regenerating their secret key.

No need to have to persist state for each session, which is nice.

Re:JWT should not be your default for sessions by barrkel on Wednesday May 12, 2021 @10:21PM (#27137721)
Where is the secret key stored? This may not be per session but it is per user, which for most apps is almost the same thing.
Re:JWT should not be your default for sessions by whateveracct on Wednesday May 12, 2021 @11:10PM (#27138006)
It's per-user. Just a column with all their other stuff.

Sessions:Users are Many:1 typically so that's not as simple

Re:JWT should not be your default for sessions by tatersolid on Thursday May 13, 2021 @11:46PM (#27150479)
So you have todo a DB call to get this key on every page load or API request?

You’re back to square one. Just use an opaque random session ID

Re:JWT should not be your default for sessions by whateveracct on Friday May 14, 2021 @01:51AM (#27151170)
I do those anyways - from my user table. But I don't have some extra table of sessions that is append-only (modulo expiration). Cuts out an entire system.
Re:JWT should not be your default for sessions by aflag on Wednesday May 12, 2021 @08:40PM (#27137048)
Why can't you just delete the cookie when the user logs out?
Re:JWT should not be your default for sessions by jrockway on Wednesday May 12, 2021 @08:46PM (#27137107)
Because the session material could be compromised. How do you revoke tokens on lost laptops? What if you accidentally checked the token into Github and realized your mistake? What if malware captured the token? You have to be able to revoke access on the server side.

You can use JWTs and have a "revoked_sessions" table that works like a normal "sessions" table. At the start of the request, check if the token is in the "revoked_sessions" table and deny access if it is. But there simply isn't a point; this has the same performance and latency considerations that a normal sessions table has ... but with many more possible ways to screw it up. "Sessions with extra steps."

Re:JWT should not be your default for sessions by lstamour on Wednesday May 12, 2021 @09:35PM (#27137459)
If the session material is routinely compromised, why use that method of storing session material? Make sure cookies are httpOnly, Secure, and where appropriate, use Strict instead of Lax.

I can understand the need to invalidate sessions server-side that might be malicious or fraudulent, to create a button in your app that says "Revoke all existing sessions", etc. And I can understand that other rules say a logged out session must not exist, and therefore you have to revoke the session. I especially agree if the JWT has sensitive roles in it, such as for an admin user.

But ... for most OAuth that uses JWT, I think keeping a short-ish expiry of say, 1 hour, combined with using cookies to store it is relatively okay. Perfect? No. But not terrible either, assuming you validate your JWT by specifying RS256 or whatever algorithm you expect, validate against cached JWKS and check both issuer and audience, issued date and/or expiry date, for example.

JWTs definitely aren't simple to validate unless you're lucky enough to use a really bullet-proof library out of the box. On the plus side, there really are only what, a half dozen steps to memorize about JWT validation. :D If new to JWTs, I highly recommend pasting one into https://jwt.ms and have a look. Yes, there's a lot to goof up, but they're relatively simple even so.

That said, I routinely use session cookies with a Redis KV session table to keep the JWT if I need it for other APIs etc. The one gotcha is making sure the random value for the session cookie doesn't already exist in Redis; using a timestamp-derived random string can help there, other than that, you're fine...

Re:JWT should not be your default for sessions by lstamour on Wednesday May 12, 2021 @09:48PM (#27137544)
Oh and this is just my two cents but - never issue your own JWTs unless you're prepared to watch for bad actors forever, ideally have an HSM to store your private key material and are prepared to publish and add keys to your JWKS so you can rotate keys "easily" if they're compromised. I would not reach for JWT when you could just as easily design an API that uses distributed KV stores to validate if a session exists. However, at scale, JWT works great. And for OAuth, that means JWT is more practical than asking a cloud provider if someone's session is valid with every request. Basically, you'll know you need to issue JWTs when the benefits outweigh the complexity of maintaining it securely.

I would say though that this advice on JWT issuing might change in future: After all, Istio made running a PKI distrubution infrastructure a lot easier than before it came along allowing for mTLS between all the things, assuming your Kubernetes is secure, of course.

And the same advice on not issuing your own JWTs applies to session cookies like Flask's that are protected only by a server-side secret. Someday you'll need to rotate that secret and when you do, everyone's sessions will vanish forever. That's probably a good thing, and not a risk you'd see frequently, but when combined with the data exposure of keeping session data in potentially clear text (or base64 encoded text) which applies equally to JWT as to cookie stored sessions, well, it can feel a lot nicer to keep session data in KV storage. If you have really long JWTs, it's more practical too, compared to sending multiple cookies each under 4KB long to store a 7KB JWT with lots of extra fields and roles, etc.

Re:JWT should not be your default for sessions by Alex3917 on Wednesday May 12, 2021 @09:20PM (#27137361)
> How do you revoke tokens on lost laptops?

Have the user change their password, and store datetime_password_last_changed on the user model. Then just treat any tokens issued before that time as expired. There are some use cases where storing tokens might be necessary, but for most startups this is probably not a good idea.

Re:JWT should not be your default for sessions by jakelazaroff on Wednesday May 12, 2021 @09:48PM (#27137538)
That's exactly the same as checking a list of tokens. If you need to make a DB trip on every request, what advantage are you getting from JWTs?
Re:JWT should not be your default for sessions by Alex3917 on Thursday May 13, 2021 @08:18AM (#27141253)
> If you need to make a DB trip on every request

There's no extra DB request, assuming you need to lookup the user model on each request already.

Re:JWT should not be your default for sessions by jakelazaroff on Thursday May 13, 2021 @09:26AM (#27141808)
In that case, you can avoid DB overhead by joining the user when you query the session. I'm still not sure what advantage JWTs have in this scenario.
Re:JWT should not be your default for sessions by spookthesunset on Thursday May 13, 2021 @12:05AM (#27138274)
> If you need to make a DB trip on every request, what advantage are you getting from JWTs?

Because you don't need to check the DB every request! That's the cool part! You only hit the DB for requests that matter!

For example, do you really need to check the DB to load this very page? If the auth token expiration is say, 5 minutes... does it really matter if a bad guy gets ahold of that token and loads this page? They can't post or vote because for those requests... you can pass the token to your auth server to be validated. 99% of your traffic is probably servicing the loading of this very page. 1% (or probably closer to 0.1%) is any kind of traffic that you actually care if the token hasn't expired within 5 minutes.

The problem people get into is they think security is black and white. It's gray. Some things need to trade latency for security... like write traffic. For 99% of the read traffic on HN? Who cares... even 10 minutes or more might be okay depending on the business.

People invent these complex pub-sub systems and stuff... they are working under the idea that all requests need to be super-secure. Most of it doesn't. I'd assert for most businesses.... 99% of the authenticated traffic could deal with a 5 minute max window after logout where somebody could maybe, theoretically impersonate somebody. And for the 1% of that traffic where it matters, you can always hit the DB.

Re:JWT should not be your default for sessions by kalleboo on Thursday May 13, 2021 @09:15AM (#27141698)
> I'd assert for most businesses

"for most businesses" you're never going to have enough traffic that a classic session database (even stored in, gasp, MySQL) would be a bottleneck.

JWT definitely has it's places but it has so much complexity, so many tradeoffs and footguns that it should only be used when you have a specific problem with a standard session system that you need to solve, not as the default.

Re:JWT should not be your default for sessions by e_y_ on Wednesday May 12, 2021 @09:12PM (#27137313)
As the article mentions in a sidenote, a time-bounded revoked sessions table is small enough to keep in memory and can be updated via pubsub for the relatively infrequent case where you need to revoke one.

It's definitely more complex but at certain scales it might be worth it.

Re:JWT should not be your default for sessions by rsj_hn on Wednesday May 12, 2021 @09:26PM (#27137413)
The "keep in memory" part is gonna be hard as you scale to multiple servers. You run into all the issues that lead people to stick an oracle DB behind their app servers. I agree that these considerations do pan out in some cases; I'm not saying that any of these proposals can't be the right way to go depending on your overall design, but now we are squarely in optimization-land and have long given up on statelessness.
Re:JWT should not be your default for sessions by hermanradtke on Wednesday May 12, 2021 @08:43PM (#27137067)
The issue is not deleting the cookie. The issue is that the JWT can still be used as a valid session unless you have some sort of blocklist. Once you introduce a blocklist, you might as well ditch the JWT and use some opaque token stored in a table.
Re:JWT should not be your default for sessions by remram on Wednesday May 12, 2021 @09:21PM (#27137375)
Is that a problem though? Does your threat model include clients that correctly send logout requests when they're supposed to but don't delete cookies when they're told?
Re:JWT should not be your default for sessions by colinclerk on Wednesday May 12, 2021 @09:44PM (#27137517)
Your application should certainly have some resolution to an account being hacked or a session token being stolen.

No expiry and no denylist means an attacker can cause problems until you patch your code.

Re:JWT should not be your default for sessions by jfgiogktkt on Wednesday May 12, 2021 @10:00PM (#27137615)
You logout on a public computer, the next user undeletes the cookie (which is just a row in a profile SQLite database).
Re:JWT should not be your default for sessions by remram on Thursday May 13, 2021 @03:24PM (#27146231)
Couldn't the previous user have rigged the app to not send the logout request, or way more plausibly installed a keylogger to get your password, which allows them to log in again at will?

I'm not disagreeing with you, it just seems to only cover a very specific type of attack, if someone else can mess with software. And of course if they can't it is unnecessary.

Re:JWT should not be your default for sessions by SigmundA on Wednesday May 12, 2021 @09:48PM (#27137543)
Never trust the client, ever.
Re:JWT should not be your default for sessions by remram on Thursday May 13, 2021 @03:48PM (#27146498)
If that's how you feel, don't trust them to logout when they walk away. Make those sessions short-lived and ask for the password again whenever they do something remotely sensitive.
Re:JWT should not be your default for sessions by SigmundA on Thursday May 13, 2021 @04:11PM (#27146774)
If you trust the client then why sign the JWT?
Re:JWT should not be your default for sessions by remram on Friday May 14, 2021 @02:06PM (#27157613)
The opposite of "never trust the client" is not "always trust the client". Build yourself a model and find out where trust and security are required.
Re:JWT should not be your default for sessions by axiosgunnar on Wednesday May 12, 2021 @08:57PM (#27137205)
the entire article could be summed up with this post tbh
Re:JWT should not be your default for sessions by kokx on Wednesday May 12, 2021 @08:44PM (#27137078)
Because a user could simply provide the cookie again on the next request. If you still see the JWT as valid even though you deleted the cookie, the user could stay logged in during that time.

Cookies are managed by the browser, hence they are ultimately controlled by the user.

Re:JWT should not be your default for sessions by spookthesunset on Wednesday May 12, 2021 @09:21PM (#27137376)
Depending on the site, that might be fine. For parts of the site that deal with sevitive data… just verify the token with the auth server every request line you would old school.

It really depends on the site and how much you care about having a window between logout and all the tokens becoming invalid. Most sites probably have large parts where it is a acceptable to have a few minute interval.

Re:JWT should not be your default for sessions by wglb on Wednesday May 12, 2021 @10:39PM (#27137837)
For a secure site, it is never acceptable to having a non-zero window.
Re:JWT should not be your default for sessions by spookthesunset on Wednesday May 12, 2021 @11:07PM (#27137993)
So all of reddit, every page, needs to reverify its auth token every request? Like, what is the worst that is gonna happen in a five minute window between logout and the token expiring? Sure make the account management pages reverify on every request... maybe even revalidate when you perform a sensitive write action (which is probably far less than 1% of the authenticated traffic). But every read request for a normal user? You are telling me that those all need to re-verify every request?

In the case of reddit, by not validating the auth token on every (non-sensitive) read request they could probably shave off 99% of the traffic going to their auth server. Better still it improves page latency as each request doesn't need to block on waiting for a response from the auth server. Faster page loads! And, since you were smart about it... all the stuff where it actually does matter that the token gets verified right away... you can do that too! It's win, win!

A lot of people mis-understand JWT or see it implemented incorrectly. JWT is pretty rad, honestly.

Re:JWT should not be your default for sessions by wglb on Thursday May 13, 2021 @12:12PM (#27143837)
> So all of reddit, every page, needs to reverify its auth token every request?

Yes.

> Like, what is the worst that is gonna happen in a five minute window between logout and the token expiring?

Complete compromise of your reddit account.

> But every read request for a normal user? You are telling me that those all need to re-verify every request?

For information that is not public, yes.

> JWT is pretty rad, honestly.

In the eyes of an attacker, absolutely.

Re:JWT should not be your default for sessions by remram on Wednesday May 12, 2021 @09:22PM (#27137382)
Why would the user (agent) do that if they've logged out?
Re:JWT should not be your default for sessions by jakereps on Wednesday May 12, 2021 @08:42PM (#27137065)
That token itself is still valid - regardless of whether or not their browser still has it stored.
Re:JWT should not be your default for sessions by wglb on Wednesday May 12, 2021 @10:35PM (#27137818)
The client may decline to delete the cookie. The server can't presume that the client will do the proper thing.
Re:JWT should not be your default for sessions by SigmundA on Wednesday May 12, 2021 @08:46PM (#27137101)
Never trust the client
Re:JWT should not be your default for sessions by speleding on Thursday May 13, 2021 @10:03AM (#27142203)
There is a much more straightforward way to handle session expiry not mentioned in the article: in most cases your application will need to get something like a "User" object from the database. That object can simply contain a version number that you increase when you need to log someone out. If the version number in the session does not match the one in the JWT you discard it.