Working with JWT is really simple - or is it?

There are a lot of libraries that eases everything related to JWT. Let it be creation, verification, etc. But still people find ways to do something stupid in their JWT handler code.

There are a lot of libraries that eases everything related to JWT. Let it be creation, verification, etc. But still people find ways to do something stupid in their JWT handler code. This is what I recently saw in one of my company's project -

The author relied on Python and python-jose project to parse and verify JWT. They were supposed to parse a RS256 signed JWT key and then return the underlying user's (the owner of JWT key) object. The code have been like -

from jose import jwt
jwt.decode("user-token-here", "public-key", algorithms=['RS256'])

The issue was that the author passed verify_signature to be False in decoding options because at that point the public key is not available to us. The flow was kinda messed up but they must have had their reasons. Anyway, not verifying signature upon decoding means that the algorithms argument won't serve its purpose and majorly the decode function won't care about public-key at all. It'll parse any and every token normally.

from jose import jwt
decoded_data = jwt.decode("user-token-here", "public-key", options={"verify_signature": False})

# <monkey business>
user = db.fetch(user = decoded_data.email)
# <monkey business>
# <JWK construct>
# <verify logic>

As per the author's flow, a JWK construct will yield the public key in later section and that will be used to verify the token at that stage BUT the user, defined in JWT, is fetched from the database before that happens. There was a bit more that the flow does that I can't mention here but somehow I could make the authenticated API to believe that I'm some other user just by changing my email in JWT.

There was one more problem in the code, I never tested for it but it kept bugging me. It's called the Algorithm confusion attacks. Read about that here.

I know that it's a very naive mistake but I don't blame the author at all. It happens to the best of us. But still it's better to stay with the default settings while decoding a JWT and changing your function's flow according to it.

Cya 🫡.