ticarpi / jwt_tool

:snake: A toolkit for testing, tweaking and cracking JSON Web Tokens
GNU General Public License v3.0
5.46k stars 670 forks source link

json encoding differences cause canary value test to fail #48

Open PaulTurner-awin opened 3 years ago

PaulTurner-awin commented 3 years ago

Firstly, thanks for a great tool!

I'm not sure there's much that can be done about this, but I wanted to log it in case anyone else has the same experience.

If the original JWT token includes a (correctly) escaped forward slash in the issuer, such as {"iss":"my.domain.com\/iss-endpoint"}, then jwt_tool fails to recognise the canary value test has been met, such as:

[+] Sending token jwttool_b5c2514b08df054d76b80e7d6a98c70d Sending token Response Code: 403, 91 bytes Running Scanning Module: Running prescan checks... [+] FOUND "clickref" in response: jwttool_86deb84549be4dcfd8661a928c5b76f8 Prescan: original token Response Code: 200, 254 bytes Canary value (myvalue) was not found in base request - check that this token is valid and you are still logged in Do you wish to continue anyway? ("Y" or "N") Here you can see the original request failed with a 403 response, this seems to be due to how the rejigToken function works.

Having spent sometime looking in to this, it appears to be due to the json decoding and re-encoding not resulting in the same result, which invalidates the original signature.

This Python code may help illustrate it more:

import json

json_string = '{"iss":"my.domain.com\/iss-endpoint"}'#

json_object = json.loads(json_string)

new_json_string = json.dumps(json_object)

if json_string == new_json_string:
        print("json remains unchanged:" + new_json_string)
else:
        print("json had changed!  original:"+ json_string + "  new:" + new_json_string)

Running this will output:

$ python example.py json had changed! original:{"iss":"my.domain.com\/iss-endpoint"} new:{"iss": "my.domain.com/iss-endpoint"}

For clarity my jwt_tool command was like: python jwt_tool.py -pd "{MY POST DATA}" -t {MY URL} -rh "Authorization: Bearer {MY JWT}" -M pb -cv "myvalue"

The escaping of the forward slash as "\/" is valid (but optional) according to the specification.

I'm not sure whether it would be possible to "fix" this in jwt_tool or not?