JWTs are insecure session tokens

Поделиться
HTML-код
  • Опубликовано: 22 ноя 2024

Комментарии • 186

  • @UpToTheWhalesNow
    @UpToTheWhalesNow 6 месяцев назад +169

    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
      @UpToTheWhalesNow 6 месяцев назад +11

      Refresh token rotation can also be used to get the expiration period shorter without requiring the user to log in frequently. Revocation is often implemented for refresh token rotation.
      Beyond that... if the expiration period for the non "protected" resources is still unacceptable, then bearer authentication is not an appropriate choice.

    • @SoloElROY
      @SoloElROY 6 месяцев назад +5

      @@UpToTheWhalesNow But even using refresh token rotation you still need some state to invalidate the incoming RT and rotate it, right?

    • @UpToTheWhalesNow
      @UpToTheWhalesNow 6 месяцев назад +9

      @@SoloElROY yup exactly, rotating the refresh token would require some statefulness 👍
      However, that's only one request per period to refresh the token that requires some state (like doing a db query). Whereas, all the other requests in between will be stateless. That works well with the main goal of token architecture, which is to decrease load & complexity by reducing the amount of state needed for authenticating requests!

    • @Caixinha-s3q
      @Caixinha-s3q 6 месяцев назад

      @@UpToTheWhalesNow Wow, now I know why gov.br uses refreshTokens + accessTokens (which as far as I remeber is JWT), thanks!

    • @budimirfilipovic8442
      @budimirfilipovic8442 6 месяцев назад

      ​@@UpToTheWhalesNow😊

  • @m4rt_
    @m4rt_ 6 месяцев назад +63

    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.

  • @WolfrostWasTaken
    @WolfrostWasTaken 6 месяцев назад +96

    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.

    • @Beakerbite
      @Beakerbite 6 месяцев назад +30

      Yet that convenience comes at the cost of user security, just as was stated in the video.

    • @brinckau
      @brinckau 6 месяцев назад

      @@user81069 Yes, absolutely. The problem is not JWT, it is the user.

    • @brinckau
      @brinckau 6 месяцев назад

      @@user81069 You are right. JWTs are great and I will continue using them.

    • @liquidpebbles
      @liquidpebbles 6 месяцев назад

      @@user81069 Just put your head in the sand.

    • @jadelynnmasker
      @jadelynnmasker 6 месяцев назад

      ​@@user81069your loss...

  • @luckbeforeleap
    @luckbeforeleap 6 месяцев назад +8

    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.

    • @dealloc
      @dealloc 6 месяцев назад +1

      Absolutely. The latter being the wrong way to use it (sessions).
      Access tokens should be short-lived (hours max, ideally minutes) regardless of the mechanism-and rely on some form of rotation (i.e. refresh tokens). If your access tokens need to live longer, don't use JWTs as it makes revocation harder.
      The first case is a great use case for JWT, because they are only used for initial authentication and verification. You can use the id token to the create an application session, and you can use the OpenID Connect Session Management extension to allow termination of application sessions. It's a great format for this, because they are so common now that you won't need to write your own error-prone implementation. On top of this, with JWKs you can also relatively easily verify the JWTs issued by the provider with public key cryptography-without needing to constantly send requests to the provider (except to renew the public keys every now and then).

  • @DavidAlsh
    @DavidAlsh 6 месяцев назад +27

    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

  • @HeyVSauce
    @HeyVSauce 6 месяцев назад +56

    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

    • @chriss3404
      @chriss3404 6 месяцев назад +1

      This is my thought as well. Especially if requests come in batches.
      I figure that excluding scenarios where its already joever, asymetric signing algorithms & a small sqlite sidecar would be goated.

    • @MiesvanderLippe
      @MiesvanderLippe 6 месяцев назад +3

      A token blacklist for a service of tens of millions of users will fit in memory. Your services can sync just the blacklist and still avoid database lookups etc.

    • @Mankepanke
      @Mankepanke 6 месяцев назад +18

      Still over engineered. No point in JWTs if you have to do a bunch of fixes that are of equal or more complexity than just skipping JWTs in the first place and use the defacto industry standard of stateful tokens.

    • @stefano_schmidt
      @stefano_schmidt 6 месяцев назад +4

      And then you lose the whole point of Jwt - statelessness

    • @gnorts_mr_alien
      @gnorts_mr_alien 6 месяцев назад +5

      checking a simple stateful session token from a db is not your bottleneck, it never will be. this is just added complexity for nothing.

  • @fadhilinjagi1090
    @fadhilinjagi1090 6 месяцев назад +29

    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

    • @luckbeforeleap
      @luckbeforeleap 6 месяцев назад +3

      OAuth2.0 (RFC 6749) does not specify the format or stateless/stateful use of an access token but it does contemplate the use of "bearer tokens" (RFC 6750). For example, Microsoft EntraID (Azure AD) implements this by issuing access tokens as JWTs. But that's OAuth2.0. The use of JWTs by a web application for handling User sessions (which is the subject of this video) is an entirely different thing.

    • @michawhite7613
      @michawhite7613 6 месяцев назад +1

      OAuth2 doesn't require it be stateful/stateless. But OpenID Connect, a common extension to OAuth2, does require JWTs. Regardless of what you use, OAuth2 does require that the tokens be revoked in certain situations (like after someone attempts to use the associated authorization token a second time), which requires at least some state.

    • @luckbeforeleap
      @luckbeforeleap 6 месяцев назад

      @@michawhite7613 I take your point about revocation but for other reader's clarity, OAuth2.0 access tokens are not single use. For the lifetime of the access token (which may be short) the client application can send it to the API as many times as the API will accept it. RFC 7009 requires that the IdP supports a token revocation endpoint for refresh tokens (but recommends for access tokens). Not all implementations support a revocation endpoint for access tokens - I think MS EntraID only supports a revocation endpoint for refresh tokens. As for OIDC, the ID Token is not designed to be revocable (as you say it is always a JWT). But again, all this is OIDC/OAuth2.0 stuff - which I realise is not the subject of the video :)

  • @m4rt_
    @m4rt_ 6 месяцев назад +38

    Authentication: use JWTs
    Sessions: Use session tokens in cookies

    • @dealloc
      @dealloc 6 месяцев назад +3

      Yes, for authentication with third-party services, or multi-tenancy, it can be used.
      Since you can receieve a signed piece of information from a provider, and verify it against provider's public keys (JWK) for additional security.
      Otherwise try to keep it simple and just use pure credentials (password/passkeys) and don't involve JWT in any auth within your application layer.
      If anything, JWT could be used for multi-service setup.

  • @shadmanrchowdhury
    @shadmanrchowdhury 6 месяцев назад +40

    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.

    • @RuiFungYip
      @RuiFungYip 6 месяцев назад +5

      Not... necessarily. If you only store the KeyID or some kind of identifier in something like redis or some other key-value store, but encode information required for authorization into the token itself like roles, scopes, etc, you can probably save some database lookups which may be more expensive then a redis key lookup for example.
      Which can add up if you have to authorize it on frequent API calls.

    • @Mankepanke
      @Mankepanke 6 месяцев назад +1

      The same number of bytes would be required to move all of that into Redis and looking them up at the same time. (Either the client needs to send it to the server on each request or Redis needs to send it to the server on each request), but you get rid of a lot of complexity and stop losing flexibility and functionality, as well as reducing risk of misconfigured JWTs.
      There's basically no reason to use JWTs and I regard them as hype-driven scams. It's not the first of the sort, considering SOAP, MongoDB, and so on.

  • @PASTRAMIKick
    @PASTRAMIKick 6 месяцев назад +3

    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

  • @josemata8865
    @josemata8865 6 месяцев назад +11

    In summary: Skill Issue

  • @vladgonzaleza8774
    @vladgonzaleza8774 6 месяцев назад +2

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

  • @SoloElROY
    @SoloElROY 6 месяцев назад +14

    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!!

    • @MaulikParmar210
      @MaulikParmar210 6 месяцев назад +7

      Mixing oAuth concepts with JWTs. All jwts can be used as oAuth token, but oAuth token can be any random string. The logic is located in how these tokens are granted and are valid or not.
      Impmementation details varies from solution to solution as they are guidelines and not specific Impmementation. You're free to use any kind of token as long as it's unique.
      This is common pitfall when people assume that JWTs also impmements oAuth, but it doesn't, however you are free to do so.

    • @SoloElROY
      @SoloElROY 6 месяцев назад

      Yeah, I'm probably mixing things up... I will definitely do more research!

  • @someguyO2W
    @someguyO2W 6 месяцев назад +18

    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.

    • @dealloc
      @dealloc 6 месяцев назад +6

      If you add state, then there's no point in the stateless part whatsoever and you're only complicating things. Anything can be protected against tampering; it's called signing and any application that deals with sessions, authentication and authorization relies on it, whether they use JWTs or not.
      You don't need JWT to sign information.

    • @ParanoicoBR
      @ParanoicoBR 6 месяцев назад +2

      ​@@deallocI agree that for most applications, JWTs are overkill. However, using JWT to handle session still has its merits. For instance, you can save a lot of db calls for authorization/authentication, even if you have token revocation, since they don't happen so often (maybe every 5 minutes for system with tight security requirements). For systems with high traffic this makes a lot difference. Also, JWT are very handy for microservices because you don't need to check an authorative auth service for every request, you simply just check the JWT.
      Also, you're right that we can sign things without JWT. But why not use an standard format that has secure library implementations in most languages?

    • @tiagosutter8821
      @tiagosutter8821 6 месяцев назад +1

      @@dealloc Why would it be so complex and why would it make it "pointless"? I wouldn't say it makes it pointless, as having the state for revoking tokens is not the same as having state for every single logged user. I can revoke tokens just fine, and I've never seen a large "state" for a revocation list. But sure, if sessions can be used just fine it is a really strong sign that JWTs are not necessary for the application, i agree, and also agree that pretty much anything can be protected against tampering without requiring JWTs, I just don't understand why it would be so complicated or why you say it would be pointless to have small state for revocations

    • @someguyO2W
      @someguyO2W 6 месяцев назад

      @@dealloc I've made this exact argument. I use jwts when I desire stateless myself.
      But as I said, there's nothing stopping you from checking state.
      And you can't escape state checking if you want revocation.
      Sure. I don't need jwts to sign anything but I prefer jwts if my tokens contain more data than simply being an identifier. It's a standard and it is portable and well supported.

    • @someguyO2W
      @someguyO2W 6 месяцев назад

      @@ParanoicoBR everything you said +1

  • @benlovell9416
    @benlovell9416 5 месяцев назад

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

  • @logusgraphics
    @logusgraphics 6 месяцев назад +9

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

    • @asdfghyter
      @asdfghyter 6 месяцев назад

      i’d say that a lack of requirements around this is an issue with the spec. if it e.g. had explicitly required some revocation mechanism for implementers, at least during some circumstances, then the spec could’ve prevented this issue.

    • @asdfghyter
      @asdfghyter 6 месяцев назад

      also, it’s more of an issue with the use than the implementation

    • @logusgraphics
      @logusgraphics 6 месяцев назад +1

      @@asdfghyter if you want to enable jwt revocation you can add a key value store or cache layer where you can keep track of the jwt validity regardless of the expiration. Why would it be a matter of the spec?

    • @asdfghyter
      @asdfghyter 6 месяцев назад +1

      @@logusgraphics it’s an issue with the spec because the spec has a responsibility to describe how to safely use the standard and what not to do

  • @agustindiaz3361
    @agustindiaz3361 5 месяцев назад

    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

  • @kartonrad
    @kartonrad 6 месяцев назад +2

    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.

    • @SoloElROY
      @SoloElROY 6 месяцев назад

      This is interesting. Do you keep a single blacklist of revoke_before by user or by token? Or is it a whitelist?
      How do you handle a single token revocation vs revoke all sessions?

  • @jackbotman
    @jackbotman 6 месяцев назад +9

    The video is good, BUTT, it should have been named "WHY WE DON'T RUN UNKNOWN EXECUTABLES ON OUR PCs"

  • @Viviko
    @Viviko 6 месяцев назад +15

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

    • @illiasukonnik9966
      @illiasukonnik9966 6 месяцев назад +7

      Because you can save a significant amount of db querries for user info. (Feature list for which users have access to) I saw that on one project with millions of users, they were running on one postgresql instance, only because that jwt feature. Off course there could be play around... but it would cause more expensive and complicated infrastructure.

    • @illiasukonnik9966
      @illiasukonnik9966 6 месяцев назад

      ​ @dealloc yeah, but if you controll user app (web of phone app), everything is changing ))
      let's say it's a phone app, you give user jwt token with permissions on application startup, and give him another token when he makes new purchase or his permissions changes in some other way.
      Issues can happen, if user uses multiple applications (phones + web UI). For that app that was not the case, 99% of users used only one phone. in case of multiple devices, tech support just gave recommendation to relaunch app.
      Also application just gave access to internal content so permission invalidation also didn't bother us. Nothing criminal will happen if user will see additional content for longer period of time (ttl for his token) or next time he restarts app

  • @canadiannomad_once_again
    @canadiannomad_once_again 6 месяцев назад +3

    Renovation only needs a redis/memcache with a ttl that exceeds the longest life of your tokens. That will generally be a very small list. Certainly smaller than the usual lookup for users on a moderately large site.

    • @Mankepanke
      @Mankepanke 6 месяцев назад +1

      A moderately large site would still only need a few megabytes at most of session tokens in a KV store, and is infinitely more flexible and a bit more secure.
      Adding all of that complexity of JWTs (try implementing it yourself if you don't know how complex they are) in order to save a sub millisecond KV lookup and then doing a KV lookup anyway to look for revokations... Just think about it. Would you approve that change if someone else did it?

  • @syntaxs.
    @syntaxs. 6 месяцев назад +2

    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.

    • @BipinMaharjan-jl9ig
      @BipinMaharjan-jl9ig 6 месяцев назад

      i think jwt does this and it also suffers from the same vulnerability.

    • @syntaxs.
      @syntaxs. 6 месяцев назад

      @@BipinMaharjan-jl9ig not necessarily. i can think of two ways this is avoidable:
      1. hashing the password, secret (or salt), and expiration together and including that in the jwt data. send this client, each jwt verification checks this field. when password changes, all tokens automatically revoke on lookup.
      you might say, well then that already adds a database lookup, but in the video and in most scenarios, everyone already has a db lookup for the user already, so you’re not spending anymore calls. a jwt defined table adds one more call.
      2. expire tokens early (say 5 mins or earlier) with refresh tokens that’s agreed on the backend based on headers that identify user session such as ip, user agent (yes can be faked but ip can’t unless under same NAT), etc etc, can even use the js to grab identifiable data about the client such as window size etc which is something would be hard to replicate if most people don’t know exactly what is being used for auth.

  • @ANONAAAAAAAAA
    @ANONAAAAAAAAA 6 месяцев назад

    I always prefer using session over JWT.
    However, if I have to use JWT to, say, cut the cost of deploying Redis, I add a field like created_at in JWT so that I can revoke it by adding server side logic which invalidates tokens created before specific timestamp and accepts only new ones.
    You can also invalidate tokens for each user, after users update passwords, by saving timestamps in DB for each user.

  • @lorcaranr
    @lorcaranr 6 месяцев назад

    That attack was just session hijacking. Google needed better security around making critical changes to an account. Like prompting for credentials when deleting a channel.

  • @vikingthedude
    @vikingthedude 4 месяца назад

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

  • @robert4445
    @robert4445 6 месяцев назад +1

    I'm confused here. In your stateful session token example, what stops an attacker from being able to intercept and use that token, like in LTT attack? It sounds like the only benefit is being able to 'revoke' once you figure out its been compromised. But also, I've read people talk about stateful JWT - in the payload, someone added a 'token number' which is tied to the User object. They can revoke old JWT's just by incrementing the token number for that user and issuing a new JWT. You don't need to track revoked tokens, and the server still has the authority.
    Am I missing something here? I really want to know if I am. I'm self taught in all of this and in learning about this stuff I've come across multiple sources which come across as authorities on this subject but say (what sounds like) contradicting things, and I have a hard time getting the facts when that happens.

    • @SoloElROY
      @SoloElROY 6 месяцев назад +1

      @robert4445 I don't think you are missing anything, but those "only benefits" and "the server still has the authority" are the main arguments of the video.
      1. It's a big benefit to be able to revoke tokens, since as you just said, nothing prevents a session token from being stolen with the same ease as a JWT. So if that happens you can revoke it. With a stateless JWT you can't.
      2. If you implement any way to check in the server if a JWT is allowed or denied (whitelist, blacklist, versioning, etc) you need to keep that state in the server and check every JWT received against that check, thus kinda defeating the purpose of a stateless token, so if you're going to do that it's the same load as if you where using only session tokens. That's it.
      Stateless JWT, easy on the server, easy on the database. Can't revoke.
      Stateful session, database hit on every call. Can revoke any time.
      Stateful JWT, database hit on every call. Can revoke any time. (A bloated session token).
      JWT + refresh: my preferred middle ground: stateless JWT + stateful refresh with database hit only when expired JWT.
      So choose your fighter!

  • @_skyyskater
    @_skyyskater 6 месяцев назад +2

    I've been saying this for years too! Horribly insecure for sessions. I've been fighting this battle since 2017, and taken heat when I refuse to use JWTs for this purpose. The whole industry has a lack of reasoning ability and cargo-cults their way through their careers.

  • @more-sun
    @more-sun 6 месяцев назад +1

    Are there examples of the other implementations?

  • @rampandey191
    @rampandey191 6 месяцев назад

    Why not use session tokens for interview service communication as well?

  • @ej3281
    @ej3281 6 месяцев назад +1

    Is a session not an inherently stateful object? I don't understand why a stateless session token makes sense at all.

    • @dotnetapp
      @dotnetapp 6 месяцев назад

      it can live even after a server restart, so there is no need for everybody to login again even after a restart.

  • @MrFedX
    @MrFedX 6 месяцев назад

    Great video! Putting solid words on thoughs that didn’t sit right with me.

  • @BipinMaharjan-jl9ig
    @BipinMaharjan-jl9ig 6 месяцев назад

    switching jwt to opaque token is an overkill. Simply implement a way to revoke jwt token when compromised by tracking active jtw token in yout jwt also opaque session token does the same.

  • @BuddhiAbeyratne
    @BuddhiAbeyratne 6 месяцев назад +3

    Refresh tokens with an id and writing session expiration code should be the default way JWT is implemented
    Jwt access tokens should be smaller in terms of expiration I mean like max 10mins small
    And when passwords are changed you should always ask for old password to prevent an account take over
    Most non startup / enterprise use cases require Microservices but most tend to not add a banable token id to their refresh token
    Some do but it’s not exposed as tools for users
    That’s where the problem is

  • @egoworks5611
    @egoworks5611 6 месяцев назад +18

    brother, constructive criticism: put more pictures rather than text, like diagrams, when talking about stuff. I understand what you say, but maybe the target audience might get drowned in words. Great video and keep going, good content!

    • @CoolestPossibleName
      @CoolestPossibleName 6 месяцев назад +4

      He's getting better. This is a bit better than his previous video

  • @Xevion
    @Xevion 6 месяцев назад

    I've been setting up sessions on my project and everytime I get a "stateless" or "JWT" library put in my face, I keep wondering: "You can't revoke session tokens. So how do you deal with compromised tokens??"

    • @xE92vD
      @xE92vD 6 месяцев назад

      In my own project, I store the JTI in a database. At every API call that requires authentication, I check if the JTI (mine is a random UUID) exists in the JTIs table. If it does not exist, the JWT (I actually use PASETO, but they're very similar) is denied and the server tries to remove the revoked JWT.

  • @minma02262
    @minma02262 5 месяцев назад

    Just ignore client-side expiration and use server-side expiration. If you don't need it don't use it.

  • @s1nistr433
    @s1nistr433 2 месяца назад

    You can just change the password in the body of the JWT and validate it on the server, if it's a different password then the server will realize it doesn't match and kick the attacker out, at that point it's up to the account owner to update it.
    I also don't get why you said they were overkill. It's just a string of encrypted text, it's far more lightweight than importing a bunch of redis libraries and having a database of sessions

  • @DudeWhoSaysDeez
    @DudeWhoSaysDeez 6 месяцев назад

    why doesnt youtube have a feature for larger youtube chanels with tons of employees? There needs to be controls for certain employees built into the system.

    • @havenselph
      @havenselph 6 месяцев назад

      Permission systems are a pain in the ass, and the current way they handle things probably makes it irritating to shift to. Going from a permissionless user based authorization to full user access system would be a huge pain and likely to have many bugs, which you don't want on something to be used for businesses

  • @ChrisAthanas
    @ChrisAthanas 6 месяцев назад +1

    Nice synopsis and agree about the use of JWT... they have their place but should not be in securing anything

  • @arcstur
    @arcstur 6 месяцев назад +14

    cookies to store session id ❤

    • @follantic
      @follantic 6 месяцев назад

      Same origin cookies with a random session id with sufficient entrophy stored in Keydb (Redis compatible) with SETX for server side revocation, automatically refreshed by middleware at the API gateway that use Set-Cookie close to expiry and short-lived asymmetric JWTs for microservice authorization. With the allowed microservice dataflow directions being [gateway -> service, service-> event bus, event bus -> service].
      That would be nice. Not that I've seen it in practice.

    • @kylekirby6424
      @kylekirby6424 6 месяцев назад

      Seriously. Keep It Simple Stupid.

  • @vlc-cosplayer
    @vlc-cosplayer 6 месяцев назад

    I thought I was dumb because I couldn't understand how JWTs worked, or what they were for. Turns out that I'm still dumb, but they're a dumb idea too, since they're worse than the existing solutions. 💀

    • @stefnirk
      @stefnirk 6 месяцев назад

      No, using JWT to limit DB calls is a good solution in a high-load system where DB is hard to scale. The problem is when you go overboard and have a 100% stateless system, JWT is a real danger.

  • @AravindhKumar007
    @AravindhKumar007 6 месяцев назад +1

    OAuth has revoke route to expire the refresh and access tokens.

    • @Mooooov0815
      @Mooooov0815 6 месяцев назад +2

      AFAIK this is RFC 7009 that also states that to be OAuth2 compliant, you only need to have a way to invalidate refresh tokens. Invalidating access tokens is still optional, even by this spec. Depending on the lifetime of the access token, there is still lots of damage to do

    • @AravindhKumar007
      @AravindhKumar007 6 месяцев назад

      @@Mooooov0815 Yes, the revoke route accept both access and refresh token as input but it'll only revoke the access token if the authorization server support it.
      The purpose of keeping the access token life time short is to reduce the misuse of token.
      The reason why developers are asked not to store access token is also for the same reason.
      If you don't store the access token, there's no way it gets stolen.
      The refresh token has to be stored in more secure places like a httponly cookie with encryption and thumbprint.

    • @AravindhKumar007
      @AravindhKumar007 6 месяцев назад

      @@Mooooov0815 Another thing to note would be is 'The clients should validate the token with Auth server before making critical decisions' this way the blacklisted token cannot perform any critical business operations.

  • @samifouad
    @samifouad 6 месяцев назад +2

    session tokens are more insecure
    you could embed authorized IPs in a JWT. you get a guarantee of who created it. and you could track expired keys in a KV store in an edge cache, avoiding db lookup.
    this video comes across as FUD.

  • @kylekirby6424
    @kylekirby6424 6 месяцев назад

    I believe the last part of your video where sending tokens only once is called a cryptographic nonce.

  • @sylarfx
    @sylarfx 6 месяцев назад +1

    But wait, you said that rolling your own auth doesnt have to be complicated in your last video, ... hm, or maybe use a battle tested 3rd party service that can revoke tokens :), I have a feeling that what you're describing is more of a skill issue rather then a technology issue

    • @Mooooov0815
      @Mooooov0815 6 месяцев назад +4

      The funny thing is: just sending a HTTP session cookie with a cryptically safe random ID that represents the server state is substantially easier than dealing with JWTs or third party auth provider. Pretty much every batteries included framework has a battle tested implementation of this approach, Django, Laravel, Rails. And there a dozens of libraries for less opinionated frameworks as well.

  • @MaulikParmar210
    @MaulikParmar210 6 месяцев назад +2

    Yes, JWTs are insecure when they handover to other programs or misc user, That's why you should keep it secure.
    Token itself isn't a problem. Token storage security is the core problem and it's already talked alot in best practices on how to deal with usecases, when to rotate keys and when to Invalidate auth even when token is correct.
    The title and video context is misleading. As it's mixing Token based authentication with session security, the session is derived from the authentication mechanism, JWT happens to be one of those mechanisms. Again sessions can also be managed with different mechanisms and ut does not talk about it.
    You can combine session tokens with auth tokens to increase security and pair best of both worlds.
    Unlike JWTs session tokens are dependent on device, issued when session started and are not secure by default. What makes them secure is cookie security most cases.
    Which again leads to talk about how tokens are stored and sent and how they are used for authorization.
    Both have their usecases outside browsers, where storage security is much higher, and it makes sense to use them.

  • @davidsiewert8649
    @davidsiewert8649 6 месяцев назад +1

    Missed the most important option: allowing to set and send the jwt using secure http cookie on the server -> so client side JS does not have access to the token but its send to the server at any request anyway.

  • @MrYerak5
    @MrYerak5 6 месяцев назад +3

    The jwt can be revoked if you add a version to the jwt, its just an implemntation of the jwt
    If you tell the server to revoke all jwt's that dont have the latest version in the paylod you will force a new jwt

    • @Mankepanke
      @Mankepanke 6 месяцев назад +5

      So you're doing a KV lookup as part of token validation? In order to skip doing a KV lookup for the token itself? Why? Just skip the JWT and avoid the redundancy and complexity.

    • @MrYerak5
      @MrYerak5 6 месяцев назад

      ​@@MankepankeWhy do a lookup, the service should know the version

    • @Mankepanke
      @Mankepanke 6 месяцев назад +1

      @@MrYerak5 so you mean you need to reconfigure and redeploy all your services and sign every single user out in order to implement "Log out this session"?

    • @MrYerak5
      @MrYerak5 6 месяцев назад

      ​@@MankepankeI get your point
      I dont mind kick all the users just in case other sessions was hijeked
      I also never keep a session for a year, the maximum i use is 8 hours
      That might not be ideal for something like youtube
      A bump in version can be achived with a message queue without redeployment

    • @Mankepanke
      @Mankepanke 6 месяцев назад

      @@MrYerak5 so by this point you've achieved:
      - Users need to log on again every 8 hours.
      - You can force expire all sessions, but not limited to individual users or sessions.
      - Users cannot see their sessions or manage them on their own.
      - You require a whole JWT library.
      - You require a job queue and handlers in all your apps to deal with delivering version numbers.
      - You need a way to persist the version numbers even if the app is redeployed or rescaled.
      If you just used a simple KV lookup for session IDs you'd gain more features with fewer moving parts and just a fraction of the complexity. You should also be able to scale up to tens of thousands of concurrent users in this architecture, and scaling it up even more would also not require much, mostly doing a cluster for your KV DB so you get local copies.

  • @BlueBetaPro
    @BlueBetaPro 6 месяцев назад +3

    Pretty sure you can revoke them, some of these problems depend on implementation details. Store the signing key in the database for each user instead of a global one, then they can reset it and revoke access, or even store one for each device session. Also you can implement two levels of JWT access, for secure pages you make sure the connection is secure but if a user is just browsing random pages that don't need to be secure then there is no need to make sure the token is fully legit, then you save a lot of database requests because often the only thing you need is the username etc to populate a template. It's been some time since I have messed around with it so I don't remember the specifics, but really blaming this event on JWTs itself is just silly to me at least without more concrete details and facts.

    • @havenselph
      @havenselph 6 месяцев назад +1

      Databases are the whole reason you use JWT, just set them to very low lifetimes

    • @Mankepanke
      @Mankepanke 6 месяцев назад +3

      Explain to me what you think you gain from using JWTs in that case.
      You do JWTs that have a lot of problems and issues to trade for a single tiny thing, which is client-side authority. Then you propose wrapping it all in mandatory DB lookups that leaves you with all the downsides and none of the supposed benefits. Just why?
      This design sounds like something a first year developer would propose. Adding complexity and then new layers of complexity to "fix" the problems caused by the first layer, instead of picking the right tool for the job and be done in the first layer.

    • @xXzennerXx
      @xXzennerXx 6 месяцев назад

      @Mankepanke when your server serves millions of requests, preventing a call to a database is a big deal. If you can have an authentication system that is secure why wouldnnt you? (as mentioned in the main comment, JWT can be secure if implemented correctly)

    • @dealloc
      @dealloc 6 месяцев назад

      ​@@xXzennerXx
      Nobody said JWTs are insecure-but context matters for where the benefits of the security is and where it falls apart.
      The problem with storing JWTs in a database is that it complicates matters much more-and complication is prone to errors and therefor risks security.
      In order to support revocation, you'd still need to validate the token per request to make sure the token is still valid for the given request. The process would require (but not limited to) these steps, for example:
      1. Receive the JWT from the user (i.e. HTTP request cookies)
      2. Deserialize the JWT and verify that it's signed by the same service.
      3. Lookup the JWT in database or cache by some identifier (for optimization).
      4. Deserialize the stored JWT and verify its validity (TTL, scopes, etc.)
      5. Verify that the stored JWT is the same as the user's.
      6. Continue handling the request based on the above conditions.
      First, there's the added overhead of de/serialization. Since JWT is arbitrary JSON it needs to be deserialized each time. In this case it needs to deserialize both the JWT from the user/request, as well as from the database at the application layer.
      Second, the entire JWT needs to be stored since it needs to be verified to make sure it is not expired. This adds additional overhead in terms of _space_. Since it is arbitrary JSON, there's no one-size fits all, and you either have to store it in a UTF-8 representable data type, like a string.
      I won't go into the heeds of database data types and their inefficiencies when it comes to storage, comparison and indexing-since firstly, it depends on the database you use, but also because it adds so much complexity for optimization that it's really not worth it.
      Let's see what the steps could be by using just opaque session token:
      1. Receive the session from the user (i.e. HTTP request cookies)
      2. Verify the authentication code of session token (sign).
      3. Lookup the session token as-is in the db or cache.
      4. Continue handling the request based on the above conditions.
      The only validation we do initially is checking the authentication of the token, to make sure that the token was issued by the same service. The authentication of tokens can be done with HMAC authentication.
      Since the opaque session token is already a string, we don't need to deserialize anything-we look it up as-is. On top of this, it is fixed-length, meaning if can store it efficiently and use it as a unique identifier for quick lookup-better performance without complexity.
      Any additional information can be stored next to the token, like expiry and associated user ID for further lookups needed. And depending on the database, the expiry could even be checked during the lookup phase itself, without the need to handle it at the application layer.

    • @xXzennerXx
      @xXzennerXx 5 месяцев назад

      @@dealloc there is no need to store tokens unless you want to allow revoking tokens per device of that user for example. And even that could be done with a different secret for each device

  • @samarnagar9699
    @samarnagar9699 6 месяцев назад

    LLL called he wants his thumbnail back xd

  • @dotnetapp
    @dotnetapp 6 месяцев назад

    you can invalidate Tokens ? There is some logic needed sure but its simple to invalidate every token older than a specific date.
    With this in the auth logic which is a simple if statement it is invalidatet.
    The user has than some kind of way to interact with this like "invalidate all tokens" button or something.

  • @robindeboer7568
    @robindeboer7568 6 месяцев назад

    Whats wrong with a jwt stored as a cookie that just holds a session id? The libraries for jwts are nice, it makes it easy and its basically identical to a session token

    • @SoloElROY
      @SoloElROY 6 месяцев назад +2

      I guess nothing wrong... In the end is a session token with extra data that your app may consume!

    • @TheIcecoldorange
      @TheIcecoldorange 6 месяцев назад

      There is nothing wrong. Jwt stored in httponly cookie with expiration is pretty fool proof.

    • @ShadoFXPerino
      @ShadoFXPerino 6 месяцев назад +4

      You have to lookup access details every time (as mentioned at 5:15), which could consume more resources than bringing along the resource ids in the jwt. If you have only one database, you'll probably have to hit it anyways so it's not a concern. If you have multiple databases and multiple microservices all across the globe, then the full permissions for a certain task might involve a lengthy search and cross-comparison through multiple different databases, possibly owned by multiple different companies. Then it's better to look them all up in a single go, sign it, and give it to the user to carry around themselves like a passport.

    • @Mankepanke
      @Mankepanke 6 месяцев назад +1

      "Why not put the groceries in the car and then carry the car home?"
      "Why not make the HOA a sovereign state with a charter and a standing army and then hold elections using a televised campaign?"
      "Why not remove the 1m Ethernet cable and replace it with two Wifi access points programmed for direct communication over their own WiFi Direct channel separate from the main network?"
      Because you're adding complexity where none is needed. You shouldn't feel the need to embed an entire system inside a working solution. Random session tokens already solve your problems, no need to embed tokens inside of JWTs inside of sessions.

  • @morebagels
    @morebagels 6 месяцев назад +1

    honestly i watched this entire thing was surprised it was 900 views and not 90k.

    • @MrYerak5
      @MrYerak5 6 месяцев назад +2

      He just uploaded it 3 hours ago

  • @modolief
    @modolief 6 месяцев назад

    Your video is giving me PTSD

  • @aarona3144
    @aarona3144 6 месяцев назад +8

    You can in fact revoke JWTs. In order to do this, you need to have an attribute in the data section that has a version number or some kind of code/key. To revoke that JWT, you bump the version number or change the code/key in your database record or wherever you're matching the token with the user. If you store this on the user record itself, you can use it to revoke ALL tokens for that user but then you wont be able to revoke specific ones. If you want that, most likely, you'll need a json column type on your user record to keep track of the token versions if you don't want to have to query multiple tables to review authentication tokens.

    • @SoloElROY
      @SoloElROY 6 месяцев назад +13

      So to revoke you gotta use state, got it

    • @justinkim7202
      @justinkim7202 6 месяцев назад +8

      This defeats the purpose of having stateless JWTs in the first place if you're checking the state of the token against some state on the server.

    • @aarona3144
      @aarona3144 6 месяцев назад +1

      Im an MVC app you have to look up a user record most likely so you can determine security policies anyway and you have to do a CRUD operation most likely anyway.
      Where do you think that information is stored when you view your user profile for any given website and it tells you, you have 4 different devices connected to your profile, some being your desktop or your iPhone or Android etc?

    • @justinkim7202
      @justinkim7202 6 месяцев назад

      @@aarona3144 If you're looking up a user record from a data source so you can determine security policies every time you get a request containing a token, you're doing it wrong.
      I suggest you take your time to really learn how JWT is meant to be used and/or how companies are implementing it.

    • @justinkim7202
      @justinkim7202 6 месяцев назад

      @@aarona3144 ​ If you're looking up a user record from some data source so you can determine security policies every time you receive a request containing a token, you're doing it wrong. You might as well just use session tokens.

  • @peterszarvas94
    @peterszarvas94 6 месяцев назад +2

    you can rewoke them by changing the secret on the server

    • @Mankepanke
      @Mankepanke 6 месяцев назад +4

      That would revoke all users.

    • @Mooooov0815
      @Mooooov0815 6 месяцев назад +1

      Rotating keys across all services is a huge ask, especially just to invalidate a single access and refresh token

    • @ShrirajHegde
      @ShrirajHegde 6 месяцев назад

      That would force log out everyone which is a terrible idea

  • @justanaveragebalkan
    @justanaveragebalkan 6 месяцев назад +2

    The problem with session tokens is that there is no way to figure out if a token is forged, something that is impossible with jtw because any change to the structure of the token would immediately change the signature and invalidate the token, while it is true that it requires some extra precaution when working with jtw and logic to invalidate them in the case of a breach, it is common practice to require MFA before exchanging the old token for a new token, which solves the vulnerability issue with stolen tokens. But yeah, initially there is nothing you can do to prevent someone from his own stupidity.

    • @melo682
      @melo682 6 месяцев назад +5

      You can't really forge a session token if your web app is following best practices and making the token sufficiently random. It doesn't encode structure or information, which makes trying to guess a session similar to trying to brute force a cryptographic signature.

    • @Mankepanke
      @Mankepanke 6 месяцев назад +3

      How can a random string that is validated be forged? What are you talking about?

    • @ImperiumLibertas
      @ImperiumLibertas 6 месяцев назад +1

      The state on a JWT cannot be forged (or any other details of the JWT) but session tokens do not store any state and therefore do not need protections from being changed.
      A possible implementation that addressed the issues from the video is to use a stateful jwt that tracks the session and requires the JWT and session to be in alignment to be considered valid. JWTs are just ways to sign data in a json object. There is nothing wrong with that until people start treating that signature as security or control which it isn't.

  • @FUnzzies1
    @FUnzzies1 6 месяцев назад +8

    This is straight up clickbait. Beyond username/ID and *maybe* role, you shouldn't store any data in the JWT. A properly designed user service allows for near instant user information lookup and storing state on a server so you don't have to perform a user look up can cause just as much bloat and headache as stateless. This just sounds like a Jr regurgitating crap his bitter Sr told him.

    • @Mankepanke
      @Mankepanke 6 месяцев назад

      JWTs are marketing-driven scams and need to be stopped.

    • @sploders1019
      @sploders1019 6 месяцев назад +3

      This comment misses the entire point of the video. The point he’s trying to make is that stateless tokens don’t allow you to revoke access. The only way to revoke a stateless token is to either change the key, triggering a re-auth for every user of the service (for large user bases, that would get annoying FAST), or to store a “revoked id list”, which adds state to be referenced on every request, in which case you may as well just put *all* the session state in there. It’s a perfectly legitimate argument, and something I’ve had to consider at my job. I’ve just opted for short expiration times in the meantime

    • @rwilliamisen
      @rwilliamisen 5 месяцев назад

      When trying to seem smart makes you look foolish.

    • @FUnzzies1
      @FUnzzies1 4 месяца назад

      Look at all the mad shitty devs.

  • @andrewlalis
    @andrewlalis 6 месяцев назад +8

    Clickbait

  • @advertslaxxor
    @advertslaxxor 6 месяцев назад +3

    You can revoke JWTs. You just need to do a database (or more better, some memcached/redis/... lookup).
    You don't even need to store the whole JWT in there.

    • @SoloElROY
      @SoloElROY 6 месяцев назад +9

      That's called state

    • @kissuosts4704
      @kissuosts4704 6 месяцев назад

      @@SoloElROY you don't have to use the state for everything

    • @advertslaxxor
      @advertslaxxor 6 месяцев назад +2

      @@SoloElROY I mean, yeah, it is state. Let me know when you figure out how to do revocation (a stateful action) without state :)

    • @SoloElROY
      @SoloElROY 6 месяцев назад +3

      @@advertslaxxor it's not possible! But that's the point of this video

    • @roboter5123
      @roboter5123 6 месяцев назад +1

      Maybe it's more obvious why this is wrong if we rephrase your comment a bit:
      You can revoke statless token. You just need State on the server.

  • @Sivirously
    @Sivirously 6 месяцев назад +1

    first.