JWT Structure and the alg: none Attack
What Is a JSON Web Token?
A JSON Web Token (JWT) — defined in RFC 7519 — is a compact, URL-safe mechanism for representing claims between two parties. It is the dominant format for stateless authentication tokens in modern web APIs.
A JWT is a string of three Base64URL-encoded sections joined by dots:
<header>.<payload>.<signature>The Three Parts
1. Header
The header is a JSON object that describes the token type and the signing algorithm:
{
"alg": "HS256",
"typ": "JWT"
}Common alg values: HS256 (HMAC-SHA256), RS256 (RSA-SHA256), ES256 (ECDSA-SHA256).
2. Payload
The payload carries the claims — assertions about the subject and metadata:
{
"sub": "user123",
"role": "user",
"email": "[email protected]",
"iat": 1700000000,
"exp": 1700003600
}Standard claims include sub (subject), iat (issued at), and exp (expiry).
3. Signature
The signature is computed over the encoded header and payload using the algorithm and key declared in the header. For HS256:
HMAC-SHA256(base64url(header) + "." + base64url(payload), secret)A valid signature proves the token has not been tampered with since it was issued by the server.
Example JWT string:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiJ1c2VyMTIzIiwicm9sZSI6InVzZXIiLCJleHAiOjk5OTk5OTk5OTl9
.a3f2b1c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0Paste any JWT into [jwt.io](https://jwt.io) to decode its parts instantly.
The alg: none Vulnerability
RFC 7518 (JSON Web Algorithms) defines "none" as a valid algorithm identifier meaning "unsecured JWS" — intended for contexts where the integrity of the token is guaranteed by other means (for example, a token passed only over a secure local IPC channel).
The critical flaw: many early JWT libraries read the alg field from the token's own header and then used that algorithm to verify the signature. An attacker who controls the token can therefore:
- Decode the token (Base64URL is encoding, not encryption — anyone can decode it).
- Change
"alg": "HS256"to"alg": "none". - Change
"role": "user"to"role": "admin"in the payload. - Strip the signature (leave only the trailing dot, or remove the dot entirely).
- Submit the modified token.
A vulnerable server reads alg: none, calls its library's verify function, which sees "no signature required" and returns success. The attacker now has admin-level access.
Historical CVEs
| CVE | Library | Year | Impact |
|---|---|---|---|
| CVE-2015-9235 | jsonwebtoken (Node.js) | 2015 | alg: none accepted; privilege escalation |
| Auth0 vulnerability | Auth0 platform | 2015 | alg: none bypass on multiple endpoints |
Lab Goal
In the JWT Workbench panel, you will:
- Inspect the pre-loaded JWT (Header and Payload panes).
- Change
algfrom"HS256"to"none". - Change
rolefrom"user"to"admin". - Remove the signature.
- Submit the forged token and observe the server's
200 Welcome, adminresponse.
Proceed to the next step to begin.