1. 12

  2. 4

    Stateless cryptography-based login tokens are also popular outside of JWT, for example Rails’s default session storage uses this approach (it also has handy MessageVerifier). So almost everything described in article applies to these session stores as well.

    1. 3

      The only problem here is that if an attacker was able to steal your token in the first place, they’re likely able to do it once you get a new token as well. The most common ways this happens is by man-in-the-middling (MITM) your connection or getting access to the client or server directly.

      For my education; is there another security mechanism that will protect from MITM or server being compromised? Seems like if your JWT token is being stolen then you’ve got bigger problems.

      1. 6

        JWTs are commonly stolen via XSS – which is particularly common today as more and more of the auth logic is being pushed into the browser which is an insecure channel.

        There are some new things browsers are attempting to implement to help mitigate this risk, including token binding, https://datatracker.ietf.org/wg/tokbind/documents/, but to my knowledge there is no active implementation of token binding in a major browser yet.

      2. 2

        Could one store the IP address of the initial request that causes you to generate a JWT in the token itself? Then you can validate that the current request comes from the same IP. If they’re different, then force them to log in again from their current IP.

        The user would need to re-login if they turn on a VPN or change locations, but that’s a small price to pay if that reduces the possibility for certain types of attacks. I’m definitely not a security expert, but working on a fairly sensitive app where a breach would be bad for a user. The fact that I haven’t seen this suggested next to more complex safeguards makes me think there’s a fundamental flaw in it that I’m just not thinking of.

        1. 5

          IPs aren’t a great factor to base stuff like this one, although that’s a good idea.

          I think what’s better is something like token binding (https://datatracker.ietf.org/wg/tokbind/documents/) which is a way to pin a certain token to a specific TLS session. This way you have some basic guarantees. But in the real world things are sorta messy =p

          1. 2

            Most home users would have to re log in every day. Services that tie my login to an IP address piss me off so much because they are constantly logging me out.

            1. 2

              The fact that I haven’t seen this suggested next to more complex safeguards makes me think there’s a fundamental flaw in it that I’m just not thinking of.

              It’s not a safe presumption that a users requests will always come from the same IP - even from request to request. Their internet access could be load balanced or otherwise change due to factors like roaming.

              1. 1

                Yeah that is also a common technique for cookies. If the remote IP changes you can invalidate the cookie.

              2. 2

                few questions:

                • Would having the jwt returned by an IdP(cognito/auth0/okta) as a result of a oauth process improve the situation?
                • any recommended way to work around this and keep stateless backend services ?
                1. 2

                  So, to answer your questions:

                  • If you’re using an authentication provider then no, it won’t really help, although… In my recommendations I mention using patterns like adaptive multi-factor authentication to re-prompt for a second factor when changes are detected – this is something Okta provides. I’m not too familiar with auth0/cognito, they might also have this functionality. So that can help a bit.

                  • There is honestly no way to have a stateless backend service without revocation. The best you can do is maintain a cache where in the cache you store any invalidated JWTs and check each request against the cache. This is a pretty common pattern.

                  But, re: stateless backend services, one thing I like to think about it is the security vs speed tradeoff. You basically have two options: either guarantee security so you aren’t servicing revoked tokens or guarantee speed and not bother with it at all. If your architecture has backend-only services that aren’t exposed to users, going for the speed tradeoff might be worth it since you’re in a trusted environment. But, if your API is servicing end-users it’s probably better to go with the approach mentioned above so you don’t run into issues :x

                2. 1

                  I’m using JWTs for something at $WORK. To implement a crude but simple token revocation, I coded the services to accept SIGHUPs to change/reload their JWT signing keys in sync. It’ll invalidate every token that exists in the wild.

                  Edit: the clients are a Linux command-line application, so it’s not a typical web workflow.