# JWT algorithm confusion: RS256 token accepted when HS256 expected

- **ID:** `security/oauth2-jwt-algorithm-confusion-rs256-hs256`
- **Domain:** security
- **Category:** auth_error
- **Verification:** ai_generated
- **Fix Rate:** 85%

## Root Cause

The JWT library is configured to accept both RS256 (asymmetric) and HS256 (symmetric) algorithms, allowing an attacker to sign a token with the public key as the HMAC secret, bypassing signature verification.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| jsonwebtoken 8.5.1 | active | — | — |
| jjwt 0.11.5 | active | — | — |
| PyJWT 2.8.0 | active | — | — |

## Workarounds

1. **In the JWT verification function, explicitly specify the allowed algorithms and reject any token that uses a different one. For example, in Node.js: jwt.verify(token, publicKey, { algorithms: ['RS256'] })** (90% success)
   ```
   In the JWT verification function, explicitly specify the allowed algorithms and reject any token that uses a different one. For example, in Node.js: jwt.verify(token, publicKey, { algorithms: ['RS256'] })
   ```
2. **Use a library that enforces a single algorithm by default, such as jose (v4+) which requires explicit algorithm selection.** (85% success)
   ```
   Use a library that enforces a single algorithm by default, such as jose (v4+) which requires explicit algorithm selection.
   ```
3. **Add a check that the 'alg' header is exactly the expected value before calling the verify function, and reject otherwise.** (80% success)
   ```
   Add a check that the 'alg' header is exactly the expected value before calling the verify function, and reject otherwise.
   ```

## Dead Ends

- **** — Simply disabling HS256 globally breaks legitimate symmetric token use cases in other parts of the system. (40% fail)
- **** — Adding a blacklist of known bad keys doesn't address the root cause — the library must enforce a single algorithm per token, not rely on external lists. (60% fail)
- **** — Upgrading the JWT library without changing the verification code may not help if the code explicitly passes both algorithms to the verifier. (30% fail)
