python-jose CVE-2026-120459 lets an empty HMAC key validate forged tokens
python-jose through 3.5.0 accepts zero-length HMAC secrets in its key wrappers, according to CVE-2026-120459. The public advisory says unauthenticated attackers can forge JWTs because HMACKey and CryptographyHMACKey accept empty keys.
The flaw is not a new signing algorithm and does not require the attacker to know a real secret. It depends on the application or library path creating an HMAC key from an empty value. If the verifier uses that empty key as the trust anchor, an attacker can sign a token with the same empty key and satisfy the signature check.
The failure is in key construction
JWT libraries often separate algorithm selection, key loading, signing, and verification. A token header names an algorithm, but the application must decide which key types and algorithms are allowed. The key wrapper then converts bytes or configuration into a signing object.
An empty secret should be rejected at the point of construction. If the wrapper accepts it, the application may continue with a key that provides no secrecy. Environment variables that are unset, secrets loaded before a vault is available, and test defaults are common ways an empty value reaches production.
The advisory is recent and marked unreviewed in the GitHub database. Teams should confirm the affected version and whether a fixed release is available from the project or their distribution. Until then, application-level rejection of empty or weak HMAC secrets is necessary. A zero-length key must not be treated as a valid fallback.
Find the dependency and the key source
Search software manifests, container images, and Python environments for python-jose. It may be a transitive dependency of an authentication package, a notebook environment, or an internal service. Record the resolved version and the package that introduced it.
Trace the configuration that supplies the HMAC secret. Search for environment variable reads, secret-manager calls, and default values. Look for code that uses an empty string when a value is missing. Raising an exception at startup is safer than silently signing with a zero-length key.
A JWT verifier should also enforce an algorithm allowlist, issuer, audience, expiry, and token type. Those checks reduce the impact of a key-construction error, although they do not replace it. A forged token still needs to pass application authorization after signature verification.
Test with the failure case
Create a test that passes an empty key to the application's token verification path. The request should fail before any claims are accepted. Repeat with a known non-empty test key and a token signed by a different key.
Check both HMACKey and CryptographyHMACKey code paths if the application uses them directly. Add a startup check that rejects missing secrets and logs a non-sensitive configuration error. Do not log the secret or a token.
Rotate and review
If an affected service may have used an empty key, rotate any token-signing material and invalidate active tokens. Review authentication logs for tokens that were accepted but did not match the expected issuer or audience. Search for unusual token lifetimes and claims that do not match the application schema.
The patch fixes the library behavior. The application still needs to stop treating an absent configuration value as a valid credential.
Top comments (0)