PyJWT: Token forgery via empty HMAC key in JWK/JWKS (GHSA-pxh4-856f-4h89)
PyJWT fails to validate empty HMAC keys when resolving from JWK or JWKS, allowing unauthenticated attackers to forge JWTs with arbitrary claims when the identity provider is misconfigured.
Triage facts
Revision 1- Applicability
- PyJWT (<= 2.13.0)
- Evidence
- Unknown
- Severity
- High
- Action
- Elevated
- Sources
- 1 public source
- Freshness
- Revision 1Oct 22, 20:04 UTC
- Source quality
- A1Likely
PyJWT versions up to 2.13.0 contain a vulnerability where HMACAlgorithm.from_jwk fails to reject empty symmetric keys (kty=oct with k=""). An attacker can forge JWTs signed with an empty HMAC key and bypass authentication if the target application resolves its signing keys from a JWK or JWKS source that publishes an empty key - a scenario typically triggered by an unset environment variable in the authentication service. This defect mirrors previously patched vulnerabilities in other JWT libraries and exposes an asymmetric verification gap compared to the existing hardened string-secret API.
Attack Chain
- An authentication service is misconfigured (e.g.,
SIGNING_SECRETis unset), resulting in a published JWKS containing an oct-type key with an emptykvalue. - The target application uses
PyJWKClientto resolve signing keys from the published JWKS. - An attacker crafts a JWT with arbitrary claims (e.g.,
role:admin) and selects the target JWK via thekidheader. - The attacker signs the forged token locally using an empty byte string as the HMAC key.
- The attacker sends the forged token in the
Authorizationheader to the target application. - The target application fetches the empty-key JWK, which
PyJWKClientprocesses into a zero-length key. - The application invokes
jwt.decodeusing the zero-length key, whichHMACAlgorithmaccepts, verifying the forged signature and granting the attacker unauthorized access.
Impact
Successful exploitation allows unauthenticated attackers to achieve full impersonation and privilege escalation by minting tokens with arbitrary claims. This affects any application using PyJWK, PyJWKSet, or PyJWKClient for key resolution.
Recommendation
- Upgrade
PyJWTto a version containing the fix for GHSA-pxh4-856f-4h89. - Audit authentication provider configurations to ensure that signing secrets are correctly populated and not defaulting to empty strings.
- Validate that published JWKS endpoints do not contain entries with empty
kvalues. - If an immediate upgrade is not possible, implement a validation layer in the application to reject
PyJWKobjects resolved with empty keys before passing them tojwt.decode.
Immediate actions
Inventory applications utilizing PyJWT PyJWKClient for JWKS key resolution
Mitigations
Upgrade PyJWT to the latest patched version
PyJWT (<= 2.13.0)