The Hacker moved to asymmetric RS256 signing with a secret private key and a public key everyone can see. But the verification code takes the algorithm from the token, so if a token arrives as HS256 it verifies it with HMAC using the public key as the secret — and the public key is published to everyone.
The same Ravens API, but it uses RS256: a private key signs, a published public key verifies. The app shows the public key. The server mistake is that it also accepts HS256 and verifies it using the public key as the HMAC secret.
Exploit the RS256-to-HS256 confusion to forge an admin token using the public key.
You forged an admin token with an HS256 signature using the public key, exploiting the algorithm confusion.
Why the solution worked
Algorithm confusion: the server expects RS256 (verified with the public key) but also accepts HS256 (verified with a shared secret), and because it reads the algorithm from the token, it uses the public key as the HMAC secret. The public key is not a secret, so the attacker signs with it. The fix: the server pins the accepted algorithm (RS256 only) and never lets the token choose it, and it keeps the verification key from ever being used as a symmetric secret. Use a library that enforces the algorithm.
The root cause
The server does not bind the key type to the algorithm, so it accepts swapping RS256 for HS256 and uses the public key — known to everyone — as the HMAC secret, which the attacker can also sign with.
How the code is fixed
The public key is published; using it as an HMAC secret turns it into an exposed secret. Pin the algorithm on the server.
Vulnerable code
function verify(token) {
const alg = parse(token).header.alg; // attacker chooses the algorithm
if (alg === 'RS256') return rsaVerify(token, PUBLIC_KEY);
if (alg === 'HS256') return hmacVerify(token, PUBLIC_KEY); // public key as HMAC secret!
}
Safe code
function verify(token) {
// Pin the algorithm; never read it from the token. HS256 is simply not allowed.
return jwt.verify(token, PUBLIC_KEY, { algorithms: ['RS256'] });
}
Impact in the real world
Algorithm confusion turns a public key into a signing secret and has allowed token forgery in real systems that rely on RS256.
How defenders detect it
Defenders pin the expected algorithm (RS256), reject HS256 explicitly, separate verification keys by type, and alert on tokens with an unexpected algorithm.