JWT Missing Claim Validation
ID |
python.jwt_missing_claim_validation |
Severity |
high |
Remediation Complexity |
low |
Remediation Risk |
high |
Remediation Effort |
low |
Resource |
Authentication |
Language |
Python |
Tags |
ASVS50:v13.3.1, CWE:287, NIST.SP.800-53, OWASP:2025:A07, PCI-DSS:6.5.10 |
Description
A JSON Web Token (JWT) is accepted without validating its iss (issuer) or aud (audience) claim.
The PyJWT options dictionary disables verify_aud or verify_iss.
Rationale
Verifying the token signature only proves that the token was signed with a trusted key; it does not prove that the token was intended for this application. When issuer or audience validation is turned off, the application accepts any validly-signed token regardless of who issued it or who it was minted for.
In multi-tenant or federated setups — several services trusting the same signing authority, or several applications sharing an identity provider — this lets an attacker present a token issued for a different application, tenant or audience and have it accepted here, an authentication bypass / token reuse across trust boundaries.
import jwt
# VULNERABLE: audience claim is not checked
data = jwt.decode(token, key, algorithms=["HS256"], options={"verify_aud": False})
Remediation
Keep issuer and audience validation enabled and configure the expected issuer(s) and audience(s), so tokens minted for anyone else are rejected. Only disable these checks when there is a deliberate, documented reason, never as a shortcut to make authentication "work".
Leave verify_aud / verify_iss enabled and pass the expected audience / issuer.
data = jwt.decode(
token, key, algorithms=["HS256"],
audience="your_api_audience",
issuer="https://issuer.example.com",
)
References
-
CWE-287 : Improper Authentication