How a tiny mistake in verifying a web token allows anyone to become a system admin.
A JSON Web Token (JWT) is used to prove who a user is. It has three parts: Header, Payload (e.g., {"user": "alice", "role": "admin"}), and a Cryptographic Signature. The server verifies the signature to ensure the payload hasn't been tampered with. However, the JWT Header specifies which algorithm was used to create the signature (e.g., "alg": "HS256"). Shockingly, the JWT specification allows an algorithm called "none". If a server blindly trusts the header, an attacker can modify their role to "admin", change the header to "alg": "none", delete the signature, and the server will accept it!
The root cause of this vulnerability is servers asking the untrusted token how it should be verified. You should never read the alg header from the token to decide your verification logic. You must hardcode the expected algorithm in your backend server code.
// BAD: Trusting the token's header
// The library reads the header, sees "none", and skips signature check!
const decoded = jwt.verify(token, mySecret);
// GOOD: Hardcoding the expected algorithm
// If the attacker changes the header to "none", this will throw an error
// because "none" is not in the allowed algorithms array.
const decoded = jwt.verify(token, mySecret, {
algorithms: ["HS256"] // STRICTLY enforce this!
});
Fixing this costs nothing in terms of performance, it's simply a configuration detail. Modern JWT libraries usually disable the "none" algorithm by default, but this exact vulnerability still appears in custom-built authentication systems or when developers use older libraries and fail to explicitly define the allowed algorithms.
"alg": "HS256" (Symmetric key). If your server is badly configured, it will try to use the public key as a symmetric password, and the signature will perfectly match! Again, strict algorithm enforcement prevents this.