Understanding JWT Attack Surfaces and How to Test Them
This article explains the structure of JSON Web Tokens, enumerates common attack vectors such as algorithm confusion, weak keys, replay, header injection, and provides practical mitigation steps and a step‑by‑step testing methodology with relevant tools and code examples.
1. JWT Overview
JSON Web Token (JWT) is a compact, JSON‑based open standard (RFC 7519) used to securely transmit claims between a client and a server. A JWT is composed of three Base64‑url‑encoded segments separated by dots: Header, Payload, and Signature.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cThe server validates a JWT by verifying the signature and, optionally, claims such as exp and aud.
2. JWT Attack Surface
2.1 Algorithm Confusion ("none" algorithm)
If the alg field in the Header is changed from a secure algorithm (e.g., HS256) to none, the server may skip signature verification and accept any payload. {"alg": "HS256", "typ": "JWT"} Modified to: {"alg": "none", "typ": "JWT"} Resulting token (signature omitted):
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VySWQiOiIxMjMifQ.Mitigation: Enforce an explicit allow‑list of algorithms and reject none. Example in Python:
payload = jwt.decode(token, secret, algorithms=["HS256", "HS512"])
user_id = payload["userId"]2.2 Weak Symmetric Keys
Low‑entropy HMAC keys enable brute‑force attacks (e.g., using jwtcrack) to recover the secret and forge valid tokens. jwtcrack your_jwt_token Mitigation: Use strong asymmetric algorithms such as RS256 with protected private keys, or generate high‑entropy symmetric keys.
payload = jwt.decode(token, public_key, algorithms=["RS256"])2.3 Replay Attacks
Captured JWTs can be reused within their validity period. Long or missing exp claims increase exposure.
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...Mitigation: Use short expiration times, include a nonce, and optionally track token identifiers to reject duplicates.
lifetime = datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
payload = {"username": username, "admin": 0, "exp": lifetime}
access_token = jwt.encode(payload, secret, algorithm="HS256")2.4 Token Leakage
Transmitting JWTs over insecure channels (HTTP) or placing them in URLs enables man‑in‑the‑middle interception.
Mitigation: Always use HTTPS and send JWTs in Authorization headers or secure cookies.
2.5 Header Parameter Injection
RFC‑registered header parameters such as jwk, jku, and kid can be abused to supply attacker‑controlled keys, resulting in self‑signed JWT acceptance.
Example jwk injection:
{"kid": "ed2Nf8sb-sD6ng0-scs5390g-fFD8sfxG", "typ": "JWT", "alg": "RS256", "jwk": {"kty": "RSA", "e": "AQAB", "kid": "ed2Nf8sb-sD6ng0-scs5390g-fFD8sfxG", "n": "yy1wpYmffgXBxhAUJzHHocCuJolwDqql75ZWuCQ_cb33K2vh9m"}}Mitigation: Validate that only trusted public keys are used, whitelist allowed jku URLs, and enforce a strict kid allow‑list.
3. Business‑Scenario Risks
3.1 Sensitive Information Exposure
The Payload is only Base64‑encoded, not encrypted. Storing personal data (e.g., SSN, email) can be read by any party with the token.
{"SSN": "123-45-6789", "email": "[email protected]", "role": "admin"}Mitigation: Store only opaque identifiers (e.g., userId) or encrypt the payload before encoding.
3.2 Improper Authorization Logic
Using the same token type for administrators and regular users without role checks can lead to privilege escalation.
POST /admin/manage/add HTTP/2
Authorization: Bearer user_token_with_low_permissionsMitigation: Verify token type and role on each endpoint and consider separate signing keys for different roles.
3.3 Cross‑Service Token Relay
Absent audience ( aud) restrictions allow a token issued for Service A to be accepted by Service B.
Host: appA
Authorization: Bearer user_token_made_by_appBMitigation: Validate the aud claim per service.
payload = jwt.decode(token, secret, audience=["appB"], algorithms=["HS256"])3.4 Injection and Privilege Escalation
Crafted payloads (e.g., {"userId":"123","role":"admin"}) can bypass checks if the server does not strictly validate token content.
Mitigation: Enforce strict signature verification, algorithm checks, and input sanitisation on all claim values.
4. JWT Testing Methodology
A systematic testing flow includes:
Locate JWTs in requests or responses.
Identify endpoints that accept JWTs.
Replay captured requests to verify token acceptance.
Check for known vulnerabilities such as:
Assess key strength for symmetric algorithms.
Verify expiration ( exp) handling and audience ( aud) validation.
Test for header‑parameter abuses (e.g., kid path traversal, jku URL manipulation).
5. Useful Tools
JWT.io – Online decoder and debugger. URL: https://jwt.io/
JWT Tool (GitHub) – Generates, attacks, and analyses JWTs. URL: https://github.com/ticarpi/jwt_tool
jwtcrack (GitHub) – Dictionary attack tool for HS256/HS384/HS512. URL: https://github.com/Sjord/jwtcrack
CyberChef – Web utility for decoding, encoding, and signing JWTs. URL: https://gchq.github.io/CyberChef/
Burp Suite plugins (e.g., sign‑saboteur) – Intercept and modify JWTs. Repository: https://github.com/d0ge/sign-saboteur
Huolala Safety Emergency Response Center
Official public account of the Huolala Safety Emergency Response Center (LLSRC)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
