Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SECURITY] Algorithm Confusion Through kid Header #274

Open
paragonie-security opened this issue Aug 20, 2021 · 0 comments
Open

[SECURITY] Algorithm Confusion Through kid Header #274

paragonie-security opened this issue Aug 20, 2021 · 0 comments

Comments

@paragonie-security
Copy link

Starting here:

python-jose/jose/jws.py

Lines 250 to 258 in be8e914

def _verify_signature(signing_input, header, signature, key="", algorithms=None):
alg = header.get("alg")
if not alg:
raise JWSError("No algorithm was specified in the JWS header.")
if algorithms is not None and alg not in algorithms:
raise JWSError("The specified alg value is not allowed")

This correctly rejects invalid alg headers, as JWT implementations MUST to be secure.

python-jose/jose/jws.py

Lines 259 to 262 in be8e914

keys = _get_keys(key)
try:
if not _sig_matches_keys(keys, signing_input, signature, alg):
raise JWSSignatureError()

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

def _get_keys(key):
if isinstance(key, Key):
return (key,)
try:
key = json.loads(key, parse_int=str, parse_float=str)
except Exception:
pass
if isinstance(key, Mapping):
if "keys" in key:
# JWK Set per RFC 7517
return key["keys"]
elif "kty" in key:
# Individual JWK per RFC 7517
return (key,)
else:
# Some other mapping. Firebase uses just dict of kid, cert pairs
values = key.values()
if values:
return values
return (key,)
# Iterable but not text or mapping => list- or tuple-like
elif isinstance(key, Iterable) and not (isinstance(key, str) or isinstance(key, bytes)):
return key
# Scalar value, wrap in tuple.
else:
return (key,)

Which is unfortunate, since the underlying verify method expects a Key object with the alg specified:

python-jose/jose/jws.py

Lines 207 to 208 in be8e914

if not isinstance(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 firebase/php-jwt#351 https://seclists.org/fulldisclosure/2021/Aug/14

Note: This particular sharp edge isn't covered by the JWT Best Practices RFC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant