JWT algorithm confusion: how RS256 tokens get forged as HS256
The token must never choose the key type. Bind each key to one algorithm, and refuse a token whose alg doesn't match the key you're about to use.
Algorithm confusion, also called key confusion, is the other classic flaw from the 2015 JWT library research. A server signs tokens with RS256 and verifies them with its public key. An attacker changes the header to HS256 and signs a forged token with HMAC, using the server's public key as the secret. A library that follows the header then checks the HMAC with that same public key, and the forgery passes.
By TechCompare · Updated
How this is calculated
The trick works because a public key isn't secret. It's on a JWKS endpoint or in the docs, so the attacker can get the exact PEM text the server holds. Older verify functions took one key argument and used the header's alg to decide how to use it. With RS256 in the header, they ran an RSA check. With HS256, they treated the same bytes as an HMAC secret, and the attacker knows those bytes. Fixes landed in the major libraries years ago, but variants keep appearing: a JWKS that lists keys without an alg, a gateway that passes a key to code that supports both families, or a custom verifier that switches on the header. The defense has three parts. Pin the algorithm in the verify call. Store the algorithm with each key, which a JWK does with its alg member, and refuse a mismatch. Keep symmetric and asymmetric keys in separate code paths. The JWT Decoder follows the same rule: an HS token is only checked with a shared secret, and if you paste something that looks like a PEM or JWK as the secret, it refuses and explains why.
Verdict
If your service only issues RS256 tokens, its verifier should reject everything else, HS256 included. Write a test that signs an HS256 token with your public key as the secret and confirm the API rejects it. That one test covers the whole attack.
More JWT scenarios
Related guides
Frequently asked questions
Is my app vulnerable to algorithm confusion?
Does using a JWKS protect me?
Can this happen with ES256 keys?
Related tools
Text Encoding Converter
Convert between Text, Base64, Binary, Hexadecimal, and Decimal formats.
Use tool ➜Unix Timestamp
Convert between Unix timestamps and human-readable dates.
Use tool ➜JSON Formatter
Validate, format, and minify JSON. Browse it as a tree, run JSONPath queries, compare two documents, or validate against a JSON Schema.
Use tool ➜