Educational demonstration

JWT Algorithm Confusion in an Authentication Service

A verifier that trusts the token's own `alg` header can be convinced to check an RSA public key as an HMAC secret.

Lab target · not a client engagement
Overview

The lab service issues RS256-signed tokens and verifies them with a helper that selects the algorithm from the token header. The RSA public key is published, as it should be — which is exactly what makes the confusion exploitable.

Findings
critical
XV-DEMO-11 · Verified by test

Verifier accepts HS256 tokens keyed with the RSA public key

Description

An attacker signs a forged token with HS256 using the public key PEM as the HMAC secret. The verifier picks HMAC from the header and validates it with the same key material.

Impact

Arbitrary token forgery, including administrator identities.

Recommendation

Pin the accepted algorithm and use key objects typed to it.

medium
XV-DEMO-12 · Verified by test

Tokens lack audience validation

Description

The aud claim is never checked, so a token issued for one service is accepted by another.

Impact

Lateral movement between services using a token from the least-protected one.

Recommendation

Validate aud, iss and exp on every verification.

Outcome

Measured in the lab: a forged role: admin HS256 token was accepted by the vulnerable verifier and rejected by the fixed one (unexpected alg). A valid token issued for a different audience was accepted by the vulnerable verifier and rejected by the fixed one (bad audience). Legitimate RS256 tokens verify in both.

Reproduce

The lab code and tests for this case study live in labs/web2 of the Xevry website repository.

cd labs/web2npm installnode --test test/jwt.test.js

Files: labs/web2/src/jwt.js · labs/web2/test/jwt.test.js

Start a conversation

Let's discuss your security needs.

Tell us what you're building. We'll respond with clear questions, an honest view of whether we're the right fit, and a scoped proposal if we are.