News for hackers. Stuff that matters.
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