Assessing JSON Web Token implementations for cryptographic weaknesses, algorithm confusion attacks, and authorization bypass vulnerabilities during security engagements.
Assessing JSON Web Token implementations for cryptographic weaknesses, algorithm confusion attacks, and authorization bypass vulnerabilities during security engagements.
During authorized penetration tests when the application uses JWT for authentication or authorization
When assessing API security where JWTs are passed as Bearer tokens or in cookies
For evaluating SSO implementations that use JWT/JWS/JWE tokens
When testing OAuth 2.0 or OpenID Connect flows that issue JWTs
During security audits of microservice architectures using JWT for inter-service authentication
How to CONFIRM a Hit (avoid false negatives)
Positive signal: a token YOU forged (alg=none, RS256→HS256 confusion, cracked HMAC secret, or kid/jku/x5u abuse) is ACCEPTED by a protected endpoint — returns 200 plus privileged data for the impersonated identity. Decoding or editing the token alone is not a finding.
Confirm by calling a real authz-gated route with the forged token and verifying the restricted resource comes back, not a login page, 401, or 403.
A 200 to an unauthenticated route is NOT a hit; one 401/403 is NOT a clean negative until you have exhausted the attack variants below.
Do NOT conclude "not vulnerable" until you have tried:
alg none in all casings (none/None/NONE/nOnE) with an empty signature.
algorithm confusion: HS256 signed with the server's RSA public key (obtain it from JWKS/openid-configuration/TLS cert and convert to PEM first).
weak secret cracking (jwt_tool/hashcat mode 16500); on success, forge and confirm acceptance.
kid injection (path traversal to empty key, SQLi) and jku/x5u pointing to attacker-hosted keys.
claim tampering (role/sub/permissions) re-signed with the recovered key, plus expired and post-logout/post-password-change replay to check revocation.
Prerequisites
Authorization: Written penetration testing agreement for the target
Python library for programmatic JWT creation and manipulation
jwt.io
Online JWT decoder for quick analysis (do not paste production tokens)
Common Scenarios
Scenario 1: Algorithm None Bypass
The JWT library accepts "alg":"none" tokens, allowing any user to forge admin tokens by simply removing the signature and changing the algorithm header.
Scenario 2: Weak HMAC Secret
The application uses HS256 with a dictionary word as the signing secret. Hashcat cracks the secret in minutes, enabling complete token forgery and admin impersonation.
Scenario 3: Algorithm Confusion on SSO
An SSO provider uses RS256 but the consumer application also accepts HS256. The attacker signs a forged token with the publicly available RSA public key using HS256.
Scenario 4: KID SQL Injection
The kid header parameter is used in a SQL query to look up signing keys. Injecting ' UNION SELECT 'attacker_secret' -- allows the attacker to control the signing key.
Output Format
## JWT Security Finding
**Vulnerability**: JWT Algorithm Confusion (RS256 to HS256)
**Severity**: Critical (CVSS 9.8)
**Location**: Authorization header across all API endpoints
**OWASP Category**: A02:2021 - Cryptographic Failures
### JWT Configuration
| Property | Value |
|----------|-------|
| Algorithm | RS256 (also accepts HS256) |
| Issuer | auth.target.example.com |
| Expiration | 24 hours |
| Public Key | Available at /.well-known/jwks.json |
| Revocation | Not implemented |
### Attacks Confirmed
| Attack | Result |
|--------|--------|
| Algorithm None | Blocked |
| Algorithm Confusion (RS256→HS256) | VULNERABLE |
| HMAC Brute Force | N/A (RSA) |
| KID Injection | Not present |
| Expired Token Reuse | Accepted (no revocation) |
### Impact
- Complete authentication bypass via forged admin tokens
- Any user can escalate to any role by forging JWT claims
- Tokens remain valid after logout (no server-side revocation)
### Recommendation
1. Enforce algorithm allowlisting on the server side (reject unexpected algorithms)
2. Use asymmetric algorithms (RS256/ES256) with proper key management
3. Implement token revocation via a blocklist or short expiration with refresh tokens
4. Validate all JWT claims server-side (iss, aud, exp, nbf)
5. Use a minimum key length of 256 bits for HMAC secrets