JWT Misconfiguration
ID |
jwt_misconfiguration |
Severity |
critical (alg=none / verify disabled) / high (hardcoded secret / exp disabled) |
Remediation Complexity |
trivial |
Remediation Risk |
high |
Remediation Effort |
low |
Family |
API2:2023 - Broken Authentication |
CWE |
CWE-347, CWE-327, CWE-757 |
Resource |
authentication |
Language |
Java, JS/TS, Python, C#, Go, PHP |
Description
Scans handler files for common JWT (JSON Web Token) security misconfigurations across Java (JJWT, com.auth0.jwt), JS/TS (jsonwebtoken, jose), Python (PyJWT, python-jose), C# (Microsoft.IdentityModel.Tokens, System.IdentityModel.Tokens.Jwt), Go (golang-jwt), and PHP (firebase/php-jwt).
Severity is tiered by signal:
-
CRITICAL — algorithm
noneaccepted (trivially forgeable tokens), or signature verification disabled. -
HIGH — hardcoded HMAC secret in source, or expiration validation disabled.
Rationale
JWT is the dominant API authentication token format, and almost every JWT failure mode collapses to the same outcome: an attacker mints a token that the server accepts as if it had been issued by the auth service. Concrete attacks the misconfigurations enable:
-
alg: noneaccepted — the attacker sends a token with the header{"alg":"none"}and an arbitrary payload. The library reads the header, sees no signature is required, and trusts the payload. This was the 2015 JJWT /node-jsonwebtokenflaw, still re-introduced regularly in hand-rolled validators. -
Signature verification disabled —
jwt.decode()instead ofjwt.verify(),verifySignature=false, the legacyparseClaimsJwt()API. Same outcome: any payload is trusted. -
Hardcoded HMAC secret — once the secret is in source, it is in the repo history, in dependency-mining bots' caches, and in every developer’s laptop. Anyone with read access to the repo can forge tokens. HMAC’s symmetry means there is no separate verify key to limit blast radius.
-
Expiration disabled — a token that never expires is a long-lived credential. Combined with one leak (browser extension, request log, MITM on a developer device, …) it becomes a permanent backdoor.
Asymmetric algorithms (RS256 / ES256) with a server-side private key avoid both the alg confusion class of attacks and the symmetric-secret problem entirely.
Remediation
-
Pin the algorithm. Validate against an explicit allowlist:
Jwts.parserBuilder().setSigningKey(key).build()(JJWT 0.11+),jwt.verify(token, key, {algorithms: ['RS256']})(jsonwebtoken),jwt.decode(token, key, algorithms=['RS256'])(PyJWT). Never accept'none'. -
Always verify. Use the
verify/validateAPI, not the rawdecode. -
Use asymmetric keys (RS256, ES256, EdDSA). The auth service signs with a private key; resource servers verify with the public key. Compromising one resource server does not let an attacker mint tokens.
-
Validate the standard claims.
exp(expiration),nbf(not-before),iss(issuer),aud(audience) — most libraries check these only if you ask. -
Never store secrets in source. Use the platform secret store (Kubernetes secret, AWS Secrets Manager, HashiCorp Vault, GitHub Actions secret) and load at runtime.
-
Don’t store sensitive data in the payload. JWT bodies are base64, not encrypted. Email addresses, role labels, and an opaque user id are typical; anything beyond that should be referenced by id and re-fetched server-side.
-
Implement revocation — short-lived access tokens + refresh-token rotation, or a denylist keyed by
jti. JWT itself does not have a built-in revocation mechanism.
Configuration
The detector recognises the dangerous JWT idioms via per-language regex over the handler file. The set of dangerous algorithms (none, HS256 with weak secrets) and the signature-bypass APIs are built in.
Unless your project wraps the standard JWT libraries behind a custom name, you typically do not need to configure this detector.
References
-
OWASP API Security Top 10 (2023) - API2:2023 - Broken Authentication.
-
CWE-347 : Improper Verification of Cryptographic Signature.
-
CWE-327 : Use of a Broken or Risky Cryptographic Algorithm.
-
CWE-757 : Selection of Less-Secure Algorithm During Negotiation ('Algorithm Downgrade').
-
OWASP Cheat Sheets Series: JWT for Java Cheat Sheet (patterns apply broadly).