def payload_add_space_to_value(jwt_string): """ Adds a space at the end of the value stored in the payload. :param jwt_string: The JWT as a string :yield: The different JWT as string """ header, payload, signature = decode_jwt(jwt_string) if isinstance(payload, dict): for key, value in payload.iteritems(): if not isinstance(value, basestring): continue payload_copy = payload.copy() payload_copy[key] = value + ' ' yield encode_jwt(header, payload_copy, signature) if isinstance(payload, list): for i, item in enumerate(payload): if not isinstance(item, basestring): continue payload_copy = payload[:] payload_copy[i] = item + ' ' yield encode_jwt(header, payload_copy, signature)
def header_kid_file_url(jwt_string): """ If the header looks like: { "alg": "RS256", "kid": "ac2b63faefcf8362f4c528e7c78433879387016b" } The result will look like: { "alg": "RS256", "kid": "file://b61078397833487c7e825c4f2638fcfeaf36b2ca" } :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) # When the JWT is signed using hashes, there is no kid if 'kid' not in header: return header['kid'] = 'file://' + header['kid'] yield encode_jwt(header, payload, signature)
def header_kid_remove(jwt_string): """ If the header looks like: { "alg": "RS256", "kid": "ac2b63faefcf8362f4c528e7c78433879387016b" } The result will look like: { "alg": "RS256", } :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) try: del header['kid'] except KeyError: # When the JWT is signed using hashes, there is no kid return yield encode_jwt(header, payload, signature)
def header_alg_none_empty_sig(jwt_string): """ If the header looks like: { "alg": "HS256", "typ": "JWT" } The result will look like: { "alg": "none", "typ": "JWT" } We also remove the signature Exactly as described in https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/ :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) header['alg'] = 'none' signature = '' yield encode_jwt(header, payload, signature)
def header_typ_remove(jwt_string): """ If the header looks like: { "alg": "HS256", "typ": "JWT" } The result will look like: { "alg": "HS256", } :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) try: del header['typ'] except KeyError: # Some JWT implementations, such as the one used by Google, doesn't # send the typ header parameter return yield encode_jwt(header, payload, signature)
def header_typ_binary_decode_error(jwt_string): """ If the header looks like: { "alg": "HS256", "typ": "JWT" } The result will look like: { "alg": "HS256", "typ": "\xc3\xb1" } In some languages (like python) encoding and decoding strings can be hard and trigger UnicodeDecodeErrors. Try this in a python console: >>> str(u'\xc3\xb1') UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128) :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) header['typ'] = '\xc3\xb1' yield encode_jwt(header, payload, signature)
def header_kid_reverse(jwt_string): """ If the header looks like: { "alg": "RS256", "kid": "ac2b63faefcf8362f4c528e7c78433879387016b" } The result will look like: { "alg": "RS256", "kid": "b61078397833487c7e825c4f2638fcfeaf36b2ca" } :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) try: header['kid'] = header['kid'][::-1] except KeyError: # When the JWT is signed using hashes, there is no kid return yield encode_jwt(header, payload, signature)
def all_empty(jwt_string): """ Completely removes all fields :param jwt_string: The JWT as a string :return: The fuzzed JWT """ yield encode_jwt('', '', '')
def signature_zero(jwt_string): """ 0x00 :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) yield encode_jwt(header, payload, '\0')
def payload_remove(jwt_string): """ Completely removes the payload :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) yield encode_jwt(header, '', signature)
def header_is_a_list(jwt_string): """ Change header type to a list: boom! :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) yield encode_jwt([], payload, signature)
def signature_reverse(jwt_string): """ Reverse the signature string :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) signature = signature[::-1] yield encode_jwt(header, payload, signature)
def payload_remove_key_value(jwt_string): """ Removes the key/value pairs stored in the payload. :param jwt_string: The JWT as a string :yield: The different JWT as string """ header, payload, signature = decode_jwt(jwt_string) if isinstance(payload, dict): for key in payload: payload_copy = payload.copy() del payload_copy[key] yield encode_jwt(header, payload_copy, signature) if isinstance(payload, list): for item in payload: payload_copy = payload[:] payload_copy.pop(item) yield encode_jwt(header, payload_copy, signature)
def payload_null_iss(jwt_string): """ Sets the iss attribute to null :param jwt_string: The JWT as a string :yield: The different JWT as string """ header, payload, signature = decode_jwt(jwt_string) if isinstance(payload, dict): payload['iss'] = None yield encode_jwt(header, payload, signature)
def payload_exp_string(jwt_string): """ Sets the exp attribute to a string :param jwt_string: The JWT as a string :yield: The different JWT as string """ header, payload, signature = decode_jwt(jwt_string) if isinstance(payload, dict): if 'exp' in payload: payload['exp'] = str(payload['exp']) yield encode_jwt(header, payload, signature)
def payload_reverse_aud(jwt_string): """ Sets the aud attribute to the reversed string of the original :param jwt_string: The JWT as a string :yield: The different JWT as string """ header, payload, signature = decode_jwt(jwt_string) if isinstance(payload, dict): if 'aud' in payload: payload['aud'] = payload['aud'][::-1] yield encode_jwt(header, payload, signature)
def payload_iss_empty(jwt_string): """ Sets the exp attribute to an empty string :param jwt_string: The JWT as a string :yield: The different JWT as string """ header, payload, signature = decode_jwt(jwt_string) if isinstance(payload, dict): if 'iss' in payload: payload['iss'] = '' yield encode_jwt(header, payload, signature)
def payload_remove_iss(jwt_string): """ Removes the iss attribute from the payload (if it exists) :param jwt_string: The JWT as a string :yield: The different JWT as string """ header, payload, signature = decode_jwt(jwt_string) if isinstance(payload, dict): if 'iss' in payload: del payload['iss'] yield encode_jwt(header, payload, signature)
def header_alg_all_possible_values(jwt_string): """ JWT RFC says that these are all the valid values for the alg field: HS256 HMAC using SHA-256 hash algorithm HS384 HMAC using SHA-384 hash algorithm HS512 HMAC using SHA-512 hash algorithm RS256 RSA using SHA-256 hash algorithm RS384 RSA using SHA-384 hash algorithm RS512 RSA using SHA-512 hash algorithm ES256 ECDSA using P-256 curve and SHA-256 hash algorithm ES384 ECDSA using P-384 curve and SHA-384 hash algorithm ES512 ECDSA using P-521 curve and SHA-512 hash algorithm If the header looks like: { "alg": "HS256", "typ": "JWT" } The result will look like: { "alg": "...", "typ": "JWT" } Where ... will be each of the valid values for the alg field. :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) original_alg = header['alg'] valid_algs = VALID_ALGS[:] # We want to yield different things, if we don't remove the original # alg we'll be yielding the exact same JWT if original_alg in valid_algs: valid_algs.remove(original_alg) for alg in valid_algs: header['alg'] = alg yield encode_jwt(header, payload, signature)
def header_alg_remove(jwt_string): """ If the header looks like: { "alg": "HS256", "typ": "JWT" } The result will look like: { "typ": "JWT" } :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) del header['alg'] yield encode_jwt(header, payload, signature)
def header_kid_none(jwt_string): """ If the header looks like: { "alg": "RS256", "kid": "ac2b63faefcf8362f4c528e7c78433879387016b" } The result will look like: { "alg": "RS256", "kid": "none" } :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) header['kid'] = 'none' yield encode_jwt(header, payload, signature)
def header_typ_invalid(jwt_string): """ If the header looks like: { "alg": "HS256", "typ": "JWT" } The result will look like: { "alg": "HS256", "typ": "invalid" } :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) header['typ'] = 'invalid' yield encode_jwt(header, payload, signature)
def payload_iss_change_one_letter(jwt_string): """ Sets the iss attribute to a slightly modified version of the original Only change the first letter to the letter a. :param jwt_string: The JWT as a string :yield: The different JWT as string """ header, payload, signature = decode_jwt(jwt_string) if isinstance(payload, dict): if 'iss' in payload: aud = list(payload['iss']) if aud[0] != 'a': aud[0] = 'a' else: aud[0] = 'b' payload['iss'] = ''.join(aud) yield encode_jwt(header, payload, signature)
def header_x5u_remove(jwt_string): """ If the header looks like: { "x5u": "key-1.cer", "alg": "RS256" } The result will look like: { "alg": "RS256" } :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) try: del header['x5u'] except: return else: yield encode_jwt(header, payload, signature)
def header_x5u_url(jwt_string): """ If the header looks like: { "x5u": "key-1.cer", "alg": "RS256" } The result will look like: { "x5u": "https://localhost/key-1.cer", "alg": "RS256" } :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) if 'x5u' not in header: return header['x5u'] = 'http://localhost/' + header['x5u'] yield encode_jwt(header, payload, signature)
def header_x5u_self_reference(jwt_string): """ If the header looks like: { "x5u": "key-1.cer", "alg": "RS256" } The result will look like: { "x5u": "/./key-1.cer", "alg": "RS256" } :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) if 'x5u' not in header: return header['x5u'] = '/./' + header['x5u'] yield encode_jwt(header, payload, signature)
def header_x5u_file_url_root(jwt_string): """ If the header looks like: { "x5u": "key-1.cer", "alg": "RS256" } The result will look like: { "x5u": "file:///", "alg": "RS256" } :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) if 'x5u' not in header: return header['x5u'] = 'file:///' yield encode_jwt(header, payload, signature)
def header_jku_dev_null(jwt_string): """ If the header looks like: { "jku": "key-1.cer", "alg": "RS256" } The result will look like: { "jku": "/dev/null", "alg": "RS256" } :param jwt_string: The JWT as a string :return: The fuzzed JWT """ header, payload, signature = decode_jwt(jwt_string) if 'jku' not in header: return header['jku'] = '/dev/null' yield encode_jwt(header, payload, signature)