Skip to content

[Security] HIGH: RSA JWK parameter validation missing; MEDIUM: SHA-1 in RSA_OAEP; algorithms=None bypass #417

Description

@Nothern131

python-jose Security Vulnerability Report

Target: https://github.com/mpdavis/python-jose (v3.5.0)
Reporter: Nothern131 (AI-assisted automated security audit)
Date: 2026-08-16

Summary

SeverityVulnerabilityFileConfirmed
HIGHRSA JWK parameter validation missingjose/backends/cryptography_backend.pyVerified
MEDIUMRSA_OAEP uses deprecated SHA-1jose/backends/cryptography_backend.py:209Verified
MEDIUMalgorithms=None skips algorithm checkjose/jws.py:257Verified
LOWUnrestricted JWS token size (DoS)jose/constants.pyVerified

HIGH: RSA JWK Parameter Validation Missing (CVSS 7.5)

File: https://github.com/mpdavis/python-jose/blob/main/jose/backends/cryptography_backend.py

The CryptographyRSAKey._process_jwk() method accepts JWK dictionaries without validating key parameters:

def_process_jwk(self, jwk_dict):
ifnotjwk_dict.get("kty") =="RSA":
raiseJWKError(...)
e=base64_to_long(jwk_dict.get("e", 256)) # Default e=256 is invalid!n=base64_to_long(jwk_dict.get("n"))
public=rsa.RSAPublicNumbers(e, n)
# No validation of n bit length, e value, or weak key detection

Issues:

  1. No minimum modulus size checkn can be arbitrarily small (e.g., 512-bit), trivially factorable
  2. Invalid default exponente defaults to 256 when not provided (should be 65537)
  3. No weak key detection — Fermat factorization, small-exponent attacks not prevented
  4. No exponent validatione must satisfy gcd(e, φ(n)) = 1

Impact: An attacker who controls a JWK Set endpoint (or can inject JWKs through kid lookup) can provide weak RSA keys. Applications using these keys for JWT verification would be vulnerable to key recovery attacks.

Fix: Add key size validation (minimum 2048 bits) and exponent validation:

e=base64_to_long(jwk_dict.get("e", 65537))
n=base64_to_long(jwk_dict.get("n"))
ifn.bit_length() <2048:
raiseJWKError("RSA modulus too small")
ife<3ore%2==0:
raiseJWKError("Invalid RSA exponent")
public=rsa.RSAPublicNumbers(e, n)

MEDIUM: RSA_OAEP Uses SHA-1 (CVSS 5.3)

File: https://github.com/mpdavis/python-jose/blob/main/jose/backends/cryptography_backend.py#L209

RSA_OAEP=padding.OAEP(padding.MGF1(hashes.SHA1()), hashes.SHA1(), None)

SHA-1 is cryptographically broken (collisions demonstrated since 2017). RSA-OAEP is deprecated in favor of RSA-OAEP-256. This definition still exists and could be used if an application explicitly requests it.

Fix: Deprecate or remove RSA_OAEP (SHA-1), or add a deprecation warning.


MEDIUM: algorithms=None Skips Algorithm Check (CVSS 5.0)

File: https://github.com/mpdavis/python-jose/blob/main/jose/jws.py#L257

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: # Skipped when algorithms=NoneraiseJWSError("The specified alg value is not allowed")

When algorithms=None (the default in jwt.decode()), the algorithm whitelist check is completely bypassed. While the current code prevents alg=none by excluding it from SUPPORTED, this is a design flaw — it relies on the algorithm list being exhaustive rather than enforcing positive restrictions.

Fix: Require algorithms to be a non-None iterable:

ifalgorithmsisNone:
raiseJWSError("algorithms parameter is required")
ifalgnotinalgorithms:
raiseJWSError("The specified alg value is not allowed")

LOW: Unrestricted JWS Token Size (CVSS 3.7)

File: https://github.com/mpdavis/python-jose/blob/main/jose/constants.py

JWE_SIZE_LIMIT = 250 * 1024 (250KB) exists but there is no equivalent limit for JWS tokens. A maliciously large JWT could cause memory exhaustion.

Fix: Add JWS_SIZE_LIMIT and enforce it during parsing.


Generated by AI Bug Bounty automated hunting tool:Reporter: Nothern131

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions