Skip to content
JWTForge

JWT Algorithm Confusion (RS256 → HS256)

Algorithm confusion tricks a server into verifying an asymmetric (RS256) token with a symmetric (HS256) algorithm, using the server's own public key — which is not secret — as the HMAC key. If it works, an attacker can mint valid tokens without the private key.

Updated 2026-06-12

How it works

An RS256 token is signed with an RSA private key and verified with the matching public key. The public key is, by design, not secret — it is often published at a JWKS endpoint.

Many libraries expose a single verify(token, key)call and choose the algorithm from the token's own alg header. An attacker changes alg from RS256 to HS256 and signs the token with HMAC, using the public key bytes as the HMAC secret. If the server passes that same public key into the verify call, it now computes an HMAC with a key the attacker also has — so the forged token verifies.

Why it matters

The whole point of asymmetric signing is that only the holder of the private key can issue tokens. Algorithm confusion collapses that guarantee: anyone with the public key (i.e. anyone) can forge tokens, escalate roles, impersonate users, and bypass authentication.

How to test for it

You cannot confirm this from the token alone — whether a server is vulnerable depends on its verification code. To test it for real:

  • Obtain the server's RSA public key (often at its JWKS URL).
  • In the Attack tab's confusion generator, paste that public key. It re-signs your token as HS256 with the key as the HMAC secret (it also tries a trailing-newline variant, which matches how many servers load key files).
  • Send the forged token to an endpoint you are authorized to test. If it is accepted, the server trusts the header's algorithm and is vulnerable.

How to fix it

  • Pin the algorithm. Configure the verifier to accept only the exact algorithm you expect (e.g. allow-list RS256 only) — never derive it from the token header.
  • Use a key type that matches the algorithm so an RSA key can never be fed to an HMAC verifier.
  • Prefer libraries whose verify API takes an explicit algorithm parameter and rejects mismatches.

Related: the alg:none attack is another header-driven bypass worth checking at the same time.