Skip to content

Algorithm-confusion guard bypassed by DER-encoded public keys (incomplete CVE-2024-33663 fix) #414

Description

@geo-chen

reported via email on 4 June 2026 - no response:

The CVE-2024-33663 fix that forbids using an asymmetric public key as an HMAC secret is incomplete. The guard in jose/backends/native.py only recognizes PEM-armored and OpenSSH-format keys:

if is_pem_format(key) or is_ssh_key(key):
raise JWKError("... should not be used as an HMAC secret.")

A DER-encoded (binary SubjectPublicKeyInfo) public key matches neither is_pem_format (PEM armor regex) nor is_ssh_key (SSH prefixes), so it passes the guard and is accepted as the HMAC secret. An attacker who knows the service's public key can then forge an HS256 token that verifies.

Verified on python-jose 3.5.0:

forged = jwt.encode({"sub":"admin","is_admin":True}, der_public_key, algorithm="HS256")
jwt.decode(forged, der_public_key, algorithms=["RS256","HS256"]) -> ACCEPTED
jws.verify(forged, der_public_key, algorithms=None) -> ACCEPTED (library default)

The PEM form of the same key is correctly blocked, so only the DER encoding bypasses the guard. This is amplified by the default algorithms=None performing no algorithm allowlist check (jose/jws.py:258).

Suggested fix: validate the key's substance rather than its text format. As PyJWT does, attempt to load the provided HMAC secret as an asymmetric key (PEM or DER) and reject it for HMAC use if it parses as one. That catches DER, PEM, and SSH encodings uniformly. Independently, consider requiring an explicit algorithms allowlist for verification.

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