I don't really understand what any of this means, maybe someone can explain it for me, I'm a little nervous to keep browsing on lemmygrad if this can apparently be exploited thru comments and posts or something?

there's disagreement about what's happening several comments down so an explanation would be appreciated

  • Flyberius [comrade/them]
    ·
    edit-2
    1 year ago

    Whose idea was that.

    It's just the reason they were designed. JWTs allow a backend to authenticate a request without checking against some stored values elsewhere (such as a list of session ids, or roles in a database), it checks that the content of your JWT, hashed with the backend's secret, matches the hash in the JWT they gave you when you first logged in. So your JWT usually contains user information such as your username/ID, the roles/authorisation your account has, and the expiry date of the token. Changing the content of your JWT causes the hash to mismatch, so the backend knows your JWT is invalid. This is great for large distributed systems where constantly checking for session IDs would create some huge amount of overhead on every request coming in. Downside of this is that a token is valid as long as it is valid. If you implement a feature to check for invalidated JWT tokens you reintroduce the problem that it is trying to fix.

    Changing your password does invalidate old tokens though

    Does it? My understanding is that if you change your password, but have a valid JWT token from prior to the password change, it is still valid. Correct me if I am wrong as this sounds like a cool feature that I would want to implement on my own backends

    • Cadende [they/them]
      ·
      edit-2
      1 year ago

      I tested it on hexbear, it does seem to get invalidated on password change. I saw the relevant GitHub commit last night but I didn't read into the exact implementation. They might somehow be adding in a password hash to the mix? Or maintaining a blocklist of invalidated jwts but that would be ugly

      But yeah. I kinda get why JWTs are like that now, but Lemmy isn't a massively distributed system and the tokens are valid for a nearly indefinite period lol. And baked into request URLs agony

      It seems like by the time you implement all the shit people are suggesting in the GitHub you've completely defeated any simplicity JWTs once had and would be better off just tracking it all in the db

      • Flyberius [comrade/them]
        ·
        edit-2
        1 year ago

        They might somehow be adding in a password hash to the mix?

        Even if you did, the JWT would still be valid if your hash changed, it would just mean that any future issued JWTs would be different. It does really sound like however it is implemented, it is being used wrong. That said, I've been doing web-dev for 2 years, and my brain melted when I looked at the lemmy stack, so what do I know?

        And baked into request URLs

        Is that not the norm? I store JWTs as html only cookies with a certain expiry date. The cookie is then sent in every request to the backend.

        One more thing I wanted to ask, maybe you can help me. I am looking at the network inspector to too see what the hexbear requests look like. Where the hell is the post data coming in from? All I can see is requests for images and svgs. Seemingly no requests to any posts api. Pretty sure I have no filters set. Am I beeing a total noob here?

        Edit: Ah, it's coming in via websocket. Weird. Ewww.

        • Cadende [they/them]
          ·
          edit-2
          1 year ago

          The websocket thing is going away when we update to the latest version (soon, I think the rebase is already done). you can look at basically any federated lemmy instance if you want to see what the network traffic looks like for the HTTP API, its pretty straightforward iirc, and there is some documentation, though it leaves a lot to be desired lol

          What I mean about the cookie is that they are (or were? haven't checked recently) literally encoding it into the URL iirc, like instead of just sending the cookie along in the headers or putting it in the request body somewhere the URL would be /api/v3/endpoint?auth=<your-JWT-here>

          And then some error pages would have the URL in the error message, so you had users posting their whole tokens when they asked for support cringe Not sure if that's fixed or not

          • Flyberius [comrade/them]
            ·
            edit-2
            1 year ago

            Oh dear. That is bad. cringe indeed.

            For the record, it doesn't look like you are doing that any more. JWTs are sent in the cookies.

            • Cadende [they/them]
              ·
              1 year ago

              You must be looking at hexbear

              lemmygrad.ml is running the latest upstream (0.18.2) and it is being sent in the URL for each API call

                  • Flyberius [comrade/them]
                    ·
                    1 year ago

                    I'm still at a bit of a loss as to how a jwt token can be invalidated by a user changing their password. Surely this means making some database query on every request, the sort of thing you are trying to avoid by using jwts in the first place.

                    Do you know anything about how this is achieved in Lemmy?

                    • Cadende [they/them]
                      ·
                      edit-2
                      1 year ago

                      Yeah, I think they are hitting the db.

                      https://github.com/LemmyNet/lemmy/pull/1493

                      If I'm understanding correctly, they are storing the last password change timestamp in the db: local_user.validator_time and then when they fetch the logged-in user details for a request they compare the timestamp of the token to that validator_time and reject the jwt if it's greater.

                      I don't think lemmy is using jwt because they really needed the low overhead, most of these requests need to hit the db regardless, they are (IMO) just using it because it was simple to use initially.

                      This does make me wonder if there are some API requests which don't call check_validator_time() and would still be usable after a pw change

                      • Flyberius [comrade/them]
                        ·
                        1 year ago

                        Thanks for the reply, that's super interesting.

                        I don't know how routing works in Rust, but I'm assuming that all requests pass through some sort of authentication middleware regardless of their final endpoint, thus logging you out of you have an invalid timestamp.

                        I really should just check myself. Thanks for all your time