Skip to content

fix(oidc): accept a token when the allowed algorithms mix key families - #189

Merged
aroff merged 1 commit into
mainfrom
fix/oidc-mixed-algorithm-families
Oct 17, 2026
Merged

aroff merged 1 commit into
mainfrom
fix/oidc-mixed-algorithm-families

Conversation

@aroff

@aroff aroff commented Oct 17, 2026

Copy link
Copy Markdown
Owner

What

OidcValidator rejected every token when OidcValidationConfig.algorithms mixed key families, e.g. [RS256, ES256].

try_validate_jwt built a single jsonwebtoken::Validation that listed every allowed algorithm. jsonwebtoken 9 refuses a key whose family differs from any algorithm in Validation::algorithms, with InvalidAlgorithm. So with [RS256, ES256], an EC key failed because RS256 was listed, and an RSA key failed because ES256 was listed. Configs with one algorithm, or one family, were not affected.

Now the token is verified with its own header alg only (Validation::new(header.alg)). The allow-list check that runs before the key lookup is unchanged.

Found while wiring Pauta's owner sign-in (rudaia-hq/pauta, spec 012). Pauta accepts RS256, Keycloak's default, and ES256, because TestIssuer mints ES256.

What could be bypassed, and the test that shows it is not

  • An algorithm outside the list. It is still refused before any key is used. Test: algorithms_of_different_families_can_be_allowed_together sends a forged HS256 header and gets UnsupportedAlgorithm, with both orders of the list.
  • Algorithm confusion: a header naming another family than the key. Validation now holds exactly one algorithm, the header's, and jsonwebtoken refuses a key of another family. The same test sends a forged RS256 header under the EC key's kid and gets UnsupportedAlgorithm.
  • An ES256 token from the right issuer validates under [RS256, ES256] and [ES256, RS256]. Without this fix the test fails, so it is a regression test.
  • Unchanged. Issuer, audience, exp/nbf, leeway and the required claims are still set on the same Validation. Every other test in multi_issuer.rs and server_validation.rs passes without changes.
  • Not affected. The browser layer (src/browser/) hardcodes [RS256], so it cannot hit this. It still has the same two-line pattern, which can be cleaned up separately.

Checks

  • cargo test -p cli-framework-oidc --all-features: all pass.
  • cargo clippy -p cli-framework-oidc --all-features -- -D warnings: clean.
  • cargo fmt --all -- --check: clean.
  • CHANGELOG: an entry under [Unreleased] → Fixed.

🤖 Generated with Claude Code

OidcValidator built one jsonwebtoken Validation with every allowed
algorithm. jsonwebtoken 9 refuses a key whose family differs from any
algorithm in that list, so a config such as [RS256, ES256] rejected
every token, RSA and EC alike.

A token is now verified with its own header alg only. The allow-list
check before key lookup is unchanged, so an alg outside the list is
still refused as UnsupportedAlgorithm, and a key is used only for the
family the token names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@aroff
aroff enabled auto-merge (squash) October 17, 2026 18:30
@aroff
aroff merged commit 7c3f206 into main Oct 17, 2026
6 checks passed
@aroff
aroff deleted the fix/oidc-mixed-algorithm-families branch October 17, 2026 18:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants