jwt-rs / jwt-ui

A command line UI for decoding/encoding JSON Web Tokens
https://jwtui.cli.rs
MIT License
171 stars 11 forks source link

decoding a jwt produces "invalid signature" error #33

Closed alaz-aura closed 4 months ago

alaz-aura commented 5 months ago

Describe the bug Decoding a jwt using jwt-ui produces an error yet the same jwt decoded in jwt.io does not show this error (message is "signature verified"

To Reproduce Steps to reproduce the behavior or a screencast

  1. Run jwt-ui
  2. Copy+ paste an encoded jwt
  3. View results

Expected behavior

Screenshot 2024-05-01 at 10 58 49 am

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

Additional context

tolik518 commented 5 months ago

Same happens to me using the main branch of jwt-ui with the key provided in the unit tests eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.XbPfbIHMI6arZ3Y922BhjWgQzWXcXNrz0ogtVhfEd2o will get me a The JWT provided has an invalid signature: InvalidSignature.

I'm using Ubuntu 20.04. The tests for me are passing, though.

How to reproduce:

  1. Get a valid JWT
  2. Test it on jwt.io
  3. Check if the signature is verified image
  4. Check the same JWT in jwt-ui -> it will produce "InvalidSignature"

Edit: This issue seems to happen because jwt-ui won't load the signature file from the server automatically, maybe this should be the standard behavior? If not standard behavior, then how about a flag to check the signature? Since this would break the offline compatibility, maybe call the flag --online to make it obvious?

Edit 2: Maybe don't show it as an error if no signature was passed? Since in most use cases, people would not pass an own signature

alaz-aura commented 5 months ago

interesting results @tolik518 . Curious what the solution is. I mean otherwise I'd just use jwt.io as that handles everything? 😅

but I did like the offline + cli nature of jwt-ui

tolik518 commented 5 months ago

hey @alaz-aura,

I don't know what the intended workflow is, but the workflow I found would be the following:

# Get token data
jwtui -sn "eyJ0...."

Then you'd need to get the url form the iss from the output. For example https://login.microsoftonline.com/8bc55320-052b-4b5f-a553-79c567cfafcd/v2.0/
Now append .well-known/openid-configuration to the issuer (this is standardized).
Sou you'll get https://login.microsoftonline.com/8bc55320-052b-4b5f-a553-79c567cfafcd/v2.0/.well-known/openid-configuration.
Request the url.
Now you get JSON containing the jwks_uri, in this case its https://login.microsoftonline.com/8bc55320-052b-4b5f-a553-79c567cfafcd/discovery/v2.0/keys.

This keys ur you can use now like this:

# Start UI with prefilled token to decode and JWKS secret from URL
jwtui -S $(curl https://login.microsoftonline.com/8bc55320-052b-4b5f-a553-79c567cfafcd/discovery/v2.0/keys) "eyJ0...."

So yeah, I'm all for automating that process by adding a --online keyword since signature verifying only works if you have gotten the keys from the issuer


Since jwtui -sn "eyJ0...." wont return valid JSON, you currently can't parse it using a json-reader like jq

deepu105 commented 5 months ago

I need to look into this. It does decode the jwt even if signature is not verified right?

tolik518 commented 5 months ago

Yeah, it still decides the JWT just fine

deepu105 commented 4 months ago

Ok I took a look and IMO this is working as expected and the error is intentional. You need to pass a supported secret format or a JWKS for signature validation to work. This tool is meant to be fully offline so it wont automatically fetch JWKS. AFAIK jwt.io does not verify signature automatically (it only does it for JWKS secrets). For the samples loaded by default the secret is hardcoded on the UI so the signature will be verified. Try pasting a JWT from outside jwt.io and it will show signature validation. It only looks up JWKS when the token is using JWKS

deepu105 commented 4 months ago

@tolik518 for valid json pass the -j

deepu105 commented 4 months ago

@alaz-aura as @tolik518 suggested the workflow in this case would be to pass the JWKS using curl or download it once and pass the file so that JWT UI remains fully offline. The JWKS will remain the same for all tokens from the same tenant.

Start UI with prefilled token to decode and JWKS secret from URL jwtui -S $(curl https://domain.auth0.com/.well-known/jwks.json) [TOKEN] if your provider has a different URL for JWKS, look for jwks_uri in https://your.idp.com/.well-known/openid-configuration