JWTs are insecure session tokens

preview_player
Показать описание
I've often seen hate for JWTs online, but never really understood why they we're seen as badly designed and insecure. So I did some digging and came to my conclusion. Which is that JWTs are a good method of authentication, but bad session tokens.

Basic opaque session tokens are usually the way to go. Using stateless tokens has many added costs, while not providing that many benefits in practice.
Рекомендации по теме
Комментарии
Автор

A common practice is to require a hard authentication when making important requests, such as editing a profile or sending a money transfer. This significantly reduces the impact of an expiration vulnerability

UpToTheWhalesNow
Автор

Technically, the reason LTT had a hard time regaining access was because the malware kept grabbing their session tokens every time they reset it.
So it wouldn't matter if it was a JWT or a normal session token for this situation, but it's still best to use normal session tokens.

mrt_
Автор

So a short lived access_token and revocable refresh_token? This is standard with AWS Cognito, Auth0 or most other OAuth2 OICD providers. Then use step-up authentication (like MFA backed tokens) for important actions

DavidAlsh
Автор

Authentication: use JWTs
Sessions: Use session tokens in cookies

mrt_
Автор

JWTs are very strong when used with an asymmetric encryption algorithm like RSA. They are a life saver in microservice environment because each service can verify the token without querying the authorization service.

WolfrostWasTaken
Автор

Some people in the comments are getting confused between (1) the use of JWTs in both OpenID Connect (mandatory JWT usage) and OAuth2.0 (JWTs very commonly issued by IdP as access tokens) and (2) JWTs used as (post-authentication) session tokens for the User's session with the web application. They are very different uses cases for JWTs.

luckbeforeleap
Автор

JWTs with short lifetimes (~10mins), constant refreshes, and an in-memory store of accounts blacklisted for refreshing after a certain timestamp (ie as part of a "cancel all sessions" feature) can help get around this limitation, whilst still limiting calls to a larger db

HeyVSauce
Автор

Skil issue.

Jwts might be stateless, but that doesn't mean you can't use stateful revocation.

A jwt is simply a data container that can be protected against tampering and encrypted.

How you're using it might be insecure, but they are not insecure by themselves.

You can fully have secure session tokens using Jwts.

someguyOW
Автор

Thank you for saying it out loud!! I have been saying this for ages. Even Oauth2 uses JWTs once and then the client is left with an opaque stateful access token

fadhilinjagi
Автор

I kind of did the same. Statelessness is great on paper but one little mistake and you're f***ed. So opted for identifiers for my JWTs and then storing the identifiers on my server. Defeats the purpose of JWTs though.

shadmanrchowdhury
Автор

refresh and access tokens sort of fixes the token revocation issue, the short life of the access tokens minimizes the impact of a token that has been compromised

PASTRAMIKick
Автор

I don't see these issues as part of the JWT spec. But more of the particular implementation.

logusgraphics
Автор

Great video. If I recall correctly, Kubernetes Service Account Tokens follow a sort of mixed approach: they create JWTs but these JWTs are bound server side to the Service Account. Therefore, there is a way to revoke access server side by removing the Service Account (which might be overkill depending on how you are using the Service Account)

I'm not saying it's the best solution, just sharing other approaches

agustindiaz
Автор

I personally like using jwts as short lived session tokens (3-5 minutes) and a random string as a refresh token.

vladgonzaleza
Автор

“You may as well use a stateful token”
But with stateful tokens you need to make a request to an auth server in the hot path. If instead you load the revoked tokens on each service as they get revoked, then you decouple the user request lifetime and the auth server interaction, since you can keep them in memory at each node.

If you are somehow expecting a huge amount of revoked tokens (which probably depends on the expiration dates of the JWTs vs. how many users you have etc), then you can instead ship a bloom filter, check for a hit, and then check the auth server to see if it’s a false positive.

benlovell
Автор

Lately I've been thinking that maybe refresh tokens could be a solution to this (I have never implemented them in a project) but just came to realize they are glorified session tokes. I see refresh tokens as a security middle ground between short lived JWT and long session tokens, but in the end you gotta keep state to make them secure.
Grat video and great explanation of the use cases!!

SoloElROY
Автор

What if we use sessions at the api gateway, and then jwts throughout our microservies?

vikingthedude
Автор

I always advocate for a revoke_before field on the subject table

This should be relatively cheap, if you need to get the subject out of your state anyway

And it adds the option to revoke all sessions.

kartonrad
Автор

Why would you store any other data in the token than just the resource IDs?

Viviko
Автор

what about when using a JWT with an expiration in the data, and it can’t be changed so the backend just verifies is the token is legit and then checks the expiration? this is a non lookup revoke.

syntaxs.