Starting here:
| def_verify_signature(signing_input, header, signature, key="", algorithms=None): |
| |
| alg=header.get("alg") |
| ifnotalg: |
| raiseJWSError("No algorithm was specified in the JWS header.") |
| |
| ifalgorithmsisnotNoneandalgnotinalgorithms: |
| raiseJWSError("The specified alg value is not allowed") |
| |
This correctly rejects invalid alg headers, as JWT implementations MUST to be secure.
| keys=_get_keys(key) |
| try: |
| ifnot_sig_matches_keys(keys, signing_input, signature, alg): |
| raiseJWSSignatureError() |
However, the algorithm associated with the key returned from _get_keys() is not validated.
| def_get_keys(key): |
| |
| ifisinstance(key, Key): |
| return (key,) |
| |
| try: |
| key=json.loads(key, parse_int=str, parse_float=str) |
| exceptException: |
| pass |
| |
| ifisinstance(key, Mapping): |
| if"keys"inkey: |
| # JWK Set per RFC 7517 |
| returnkey["keys"] |
| elif"kty"inkey: |
| # Individual JWK per RFC 7517 |
| return (key,) |
| else: |
| # Some other mapping. Firebase uses just dict of kid, cert pairs |
| values=key.values() |
| ifvalues: |
| returnvalues |
| return (key,) |
| |
| # Iterable but not text or mapping => list- or tuple-like |
| elifisinstance(key, Iterable) andnot (isinstance(key, str) orisinstance(key, bytes)): |
| returnkey |
| |
| # Scalar value, wrap in tuple. |
| else: |
| return (key,) |
Which is unfortunate, since the underlying verify method expects a Key object with the alg specified:
| ifnotisinstance(key, Key): |
| key=jwk.construct(key, alg) |
Consequently, it's possible to use a set of keys with mismatching algorithms (i.e. in frameworks that consume this library), which would in turn make those libraries susceptible to algorithm confusion (see also: the HS256/RS256 attack from a few years ago).
This is identical to the problem in googleapis/php-jwt#351https://seclists.org/fulldisclosure/2021/Aug/14
Note: This particular sharp edge isn't covered by the JWT Best Practices RFC.
Starting here:
python-jose/jose/jws.py
Lines 250 to 258 in be8e914
This correctly rejects invalid
algheaders, as JWT implementations MUST to be secure.python-jose/jose/jws.py
Lines 259 to 262 in be8e914
However, the algorithm associated with the key returned from
_get_keys()is not validated.python-jose/jose/jws.py
Lines 217 to 247 in be8e914
Which is unfortunate, since the underlying
verifymethod expects aKeyobject with the alg specified:python-jose/jose/jws.py
Lines 207 to 208 in be8e914
Consequently, it's possible to use a set of keys with mismatching algorithms (i.e. in frameworks that consume this library), which would in turn make those libraries susceptible to algorithm confusion (see also: the HS256/RS256 attack from a few years ago).
This is identical to the problem in googleapis/php-jwt#351https://seclists.org/fulldisclosure/2021/Aug/14
Note: This particular sharp edge isn't covered by the JWT Best Practices RFC.