none: The Unsecured JWT Algorithm
An alg value of none means the token is unsecured: the third part is empty and nothing is verified. It exists in the specification for cases where integrity is already guaranteed elsewhere, and it is the source of the best known JWT vulnerability.
At a glance
- Algorithm
- none, no digital signature or MAC performed
- Registered in
- RFC 7518 section 3.6, as an Unsecured JWS in RFC 7515
- Implementation requirement
- Optional
- Key
- None. There is no key and nothing to check.
- Signature size
- Zero bytes. The token ends with a dot and an empty third part.
- Verified in the decoder
- No, and it says so. There is no signature to check, and the validation list flags the token as unsigned and untrustworthy.
In detail
RFC 7515 calls this an Unsecured JWS and the encoding is exactly what it sounds like: header and payload as normal, then a dot and nothing after it. The intended use is a token whose integrity is already assured by the transport or by an enclosing structure, such as a JWT that is itself the payload of a signed or encrypted outer token. Standing alone it asserts nothing whatsoever.
The attack is trivial and it has worked against real libraries. Take a valid signed token, change alg in the header to none, delete the signature, keep the trailing dot, and send it. A verifier that reads the algorithm from the token and dispatches on it will select the none handler, find nothing to check, and report success. The attacker rewrites any claim they like on the way, admin flags included.
The defence is not to blocklist the string none, since case variations and creative encodings have got past exactly that check. The rule is to pin the accepted algorithms in configuration and reject a token whose header does not match, treating the header as a hint about how to check rather than as an instruction about whether to check. Modern libraries refuse none unless it is explicitly enabled, and that setting should stay off.
In the decoder a none token decodes like any other, so the header, payload and claims are all readable. The tool states that there is no signature to verify and its validation list flags the algorithm as none with a warning that the token is unsigned and should not be trusted. Decoding an unsigned token is useful; treating it as evidence of anything is not.
Examples
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTczNTY5MzIwMH0.
// Header: { "alg": "none", "typ": "JWT" }
// Payload: { "sub": "admin", "exp": 1735693200 }
// Signature: empty, but the trailing dot is still requiredConstructed sample. Anyone can produce this in seconds, which is the entire point.
Things that catch people out
- Filtering on the exact string none. Variations in case have defeated that check before; pin the allowed algorithms instead.
- Leaving the third part off entirely. A valid unsecured token still has two dots, and dropping the last one makes it malformed rather than unsigned.
- Accepting an unsecured token because it decoded cleanly and the claims looked right. The claims were written by whoever sent it.
Try it: JWT Decoder
Paste a token to decode the header and payload, read the claims and expiry, and verify the signature in your browser. Nothing is uploaded.
JWT Decoder
LOCAL · Browser-OnlyDecode and inspect JSON Web Tokens without sending them to a server
Related JWT claims and algorithms
All jwt claims and algorithms →alg (Algorithm) Header Parameter in a JWT
The alg header names the algorithm used to sign a JWT. Why the accepted algorithms belong in configuration, and what the decoder does with the value.
HS256: HMAC with SHA-256 in a JWT
HS256 signs a JWT with a shared secret using HMAC and SHA-256. Key sizing, the algorithm confusion attack, and verifying one in your browser.
EdDSA: Edwards-curve Signatures in a JWT
EdDSA signs a JWT with Ed25519 or Ed448 under the OKP key type. What RFC 8037 defines, why it is deterministic, and why the decoder cannot verify it.
typ (Type) Header Parameter in a JWT
The typ header declares the media type of a token. Why at+jwt exists, how typ prevents cross token confusion, and what the decoder flags.
cty (Content Type) Header Parameter in a JWT
The cty header describes the payload rather than the token. How the value JWT signals a nested token, and when nesting is actually worth it.
kid (Key ID) Header Parameter in a JWT
The kid header says which key signed a token. How rotation depends on it, why the value must be a lookup and never a path, and decoder behaviour.
Tools for this
- JWT Decoder Free online JWT decoder - decode and inspect JSON Web Tokens without sending them to a server