This article explains JWT algorithm confusion, a critical vulnerability where a token verifier trusts the algorithm specified in the token's header rather than enforcing a fixed algorithm. An attacker exploits this by switching an RS256 token to HS256 and signing it with the server's public key, which the verifier then accepts as an HMAC secret. The vulnerability is well-documented and maps to OWASP Top 10 Identification and Authentication Failures, making understanding and defending against it essential for securing JWT implementations.
- RS256 versus HS256 algorithm differencesRS256 uses asymmetric cryptography where a private key signs and a public key (known to everyone) verifies the signature. HS256 uses symmetric cryptography where an HMAC is computed with a shared secret that both parties know. The fundamental difference is that RS256 verification requires only public information, while HS256 verification requires secret information.
- How the algorithm confusion attack worksAn attacker takes a valid RS256 token, modifies its header to claim HS256, changes the payload (such as setting role to admin), then signs it with HMAC using the public key as the secret. When the verifier reads the alg header, it sees HS256, retrieves the public key it has on file, and uses it as the HMAC secret—which matches because the attacker signed with that same key. The signature validates and the forged token is accepted.
- Why public keys work as HMAC secretsRS256 public keys are intentionally disclosed because verification requires them and nothing secret is derived from them. However, when a verifier mishandles the algorithm and treats HS256 verification as symmetric, it reinterprets the public key bytes as the shared HMAC secret. Since the public key is known and the attacker can compute the HMAC with it, they can produce a valid signature that the vulnerable verifier accepts.
- Core defense: hard-code the algorithmThe primary mitigation is to pin the expected algorithm at the verifier and reject any token whose header claims a different algorithm. This prevents the attacker from switching from RS256 to HS256. The article emphasizes this as the central principle: never let the token's alg header decide how its signature is checked.
- Secondary defenses and library selectionUse type-specific keys so a public verification key cannot be repurposed as an HMAC secret. Additionally, prefer JWT libraries that require you to explicitly specify the algorithm rather than reading it from the token. Validate all standard claims (issuer, audience, expiry) in addition to the signature to add defense in depth.
- Distinction from the none algorithm bugWhile both vulnerabilities stem from trusting the alg header, the none algorithm bug removes the signature entirely, whereas algorithm confusion preserves a valid-looking signature but computed with the wrong key type. Both represent a fundamental failure to enforce security policy at the verifier.
- Real-world prevalence and standards mappingAlgorithm confusion is described as a well-documented JWT flaw that multiple JWT libraries have shipped with over the years. It maps to OWASP Top 10 (2021) category A07: Identification and Authentication Failures, indicating its significance in production systems.
- Testing for the vulnerability in authorized assessmentsWhen testing JWT authentication in systems you are authorized to assess, attempt to change the alg header to HS256 and separately to none. A verifier that accepts either change is trusting the token to describe its own security properties, indicating the presence of this vulnerability.
Bottom line: JWT algorithm confusion exploits verifiers that trust the token's alg header instead of enforcing a fixed algorithm; defenders must hard-code the expected algorithm at verification time and reject any token claiming a different one. The vulnerability is preventable through disciplined implementation practices and careful library selection, but remains a real-world risk in systems that allow tokens to control their own verification method.
alg header to decide how to check the signature. Tell it HS256 and it will verify with a symmetric key — and the only key it has is the public one everybody knows.📋 In this walkthrough
What this lab teaches
JWT algorithm confusion exploits a verifier that trusts the token's alg header. RS256 (asymmetric) verifies with a public key; HS256 (symmetric) verifies by re-computing an HMAC with a shared secret. If the verifier lets the token choose the algorithm, an attacker switches it to HS256 and signs with the public key — which, for HS256, is now a secret both sides 'share'.
The lesson: 'verify with this key' means different things for different algorithms. Letting the token pick the algorithm breaks that assumption.
How AuthBox verifies its tokens
AuthBox hands out RS256 tokens and publishes its public key, as RSA systems do. Its verifier, though, reads the alg header and picks the matching routine. Because the public key is known, an attacker can forge an HS256 token whose 'secret' is that public key, and the verifier will accept it.
The attack approach
- Note the tokens are RS256 and the public key is available, as it is meant to be.
- Change a token's header to claim HS256 and set the role claim to admin.
- Sign the modified token with HMAC, using the public key bytes as the HMAC secret.
- Present it. The verifier follows the alg header, runs HMAC with the public key, and the signature checks out.
Full walkthrough (spoiler)
If the forged token is rejected, the key bytes or the header are not quite right — open the steps.
Show the step-by-step solution
- Take a valid token and change its header algorithm from RS256 to HS256.
- Set the payload's role claim to admin.
- Compute the HMAC signature over the new header and payload, using the server's public key as the HMAC secret.
- Send the token. The verifier reads alg=HS256, HMACs with the public key it holds, gets a match, and trusts the admin claim. The lab detects the valid admin token and marks you solved.
Why it works
RS256 and HS256 both 'use a key', but in opposite ways: RS256 verifies with the public half of a key pair, while HS256 verifies with a shared secret. A verifier that obeys the token's alg header lets the attacker reinterpret the well-known public key as the shared HMAC secret. The signature is valid by the rules the attacker chose.
Where this happens in the real world
Algorithm confusion is a well-documented JWT flaw, and several JWT libraries over the years have shipped verifiers permissive enough to allow it. It — together with the related 'none' algorithm bug — is why security guidance insists on hard-coding the accepted algorithm. It maps to the Identification and Authentication Failures category (A07) in the OWASP Top 10 (2021).
How to defend against it
- Hard-code the accepted algorithm at the verifier and reject tokens whose header says anything else.
- Use separate, type-specific keys so a public verification key is never usable as an HMAC secret.
- Prefer libraries that require you to specify the algorithm rather than reading it from the token.
- Validate all standard claims (issuer, audience, expiry) in addition to the signature.
Try it, then go further
Reading about it is the easy part. Open the lab, try your own approach before peeking at the spoiler, and see how many attempts it takes.
