CVE regression matrix
When a CVE is published against another OIDC / OAuth / JOSE implementation, the question for this library is "could the same defect reach us, and if not, why not?". The honest answer needs more than a code review — it needs a test that fails the build if a future refactor reintroduces the bypass.
This page is the public ledger of those tests. Every CVE listed here has at least one unit / fuzz test that exercises the surface and pins the rejection. The test references are stable — if a row points at a file or test name, it lives in the repository.
Reading the table
- CVE — the original disclosure, against another implementation. We do not maintain CVE entries against this library; the field tells you what class of defect the test is meant to keep out.
- Class — the underlying defect (alg confusion, redirect-uri matching, PKCE downgrade, ...).
- RFC anchor — the spec section the test pins behaviour against.
- Test — the regression test that fails if the surface regresses.
JOSE / JWT verification
| CVE | Class | RFC anchor | Test |
|---|---|---|---|
| CVE-2015-9235 (jsonwebtoken) | alg=none accepted | RFC 8725 §3.1 | internal/jose.FuzzJOSEParse (alg=none seed)internal/tokens.TestVerify_AlgConfusion_HSUsingECPublicKeyBytesAsSecret |
| CVE-2016-10555 (jwt-simple) | alg=HS256 accepted, treats public key as HMAC secret | RFC 8725 §2.1 | internal/tokens.TestVerify_AlgConfusion_HSUsingECPublicKeyBytesAsSecret |
| CVE-2015-2951 (jose4j) | alg=none accepted | RFC 8725 §3.1 | internal/jose.FuzzJOSEParse |
| CVE-2024-54150 (cjwt) | algorithm confusion | RFC 8725 §2.1 | internal/tokens.TestVerify_AlgConfusion_HSUsingECPublicKeyBytesAsSecret |
| CVE-2026-22817 / -27804 / -23552 (Hono JWT 2026 cluster) | case-variant alg=NONE bypass of deny-list | RFC 8725 §3.1 | internal/jose.TestParseAlgorithm_CaseVariantsRejectedinternal/jose.FuzzJOSEParse (case-variant seeds) |
| CVE-2026-33322 (MinIO OIDC) | algorithm confusion | RFC 8725 §2.1 | internal/tokens.TestVerify_AlgConfusion_HSUsingECPublicKeyBytesAsSecret |
| CVE-2018-0114 (Cisco / node-jose) | trusted jwk header — verifier used key from JWS itself | RFC 8725 §3.1–3.5 | internal/jose.TestParseSigned_HeaderInjection_NeverFetchesinternal/jose.FuzzJOSEParse (jku seed) |
| CVE-2018-1000531 (inversoft prime-jwt) | alg header downgrade + trusted jwk | RFC 8725 §3.1 | internal/jose.TestParseSigned_HeaderInjection_NeverFetches |
| CVE-2017-11424 (python-jose-style) | jku resolved from header | RFC 8725 §3.1 | internal/jose.TestParseSigned_HeaderInjection_NeverFetches |
| CVE-2019-7644 (Auth0 jsonwebtoken-koa) | trusted jwk header | RFC 8725 §3.1 | internal/jose.TestParseSigned_HeaderInjection_NeverFetches |
| CVE-2025-59420 (Authlib) | crit extension list ignored | RFC 7515 §4.1.11 / RFC 8725 §3.5 | internal/jose.TestParseSigned_CritHeaderRejectedAtVerify |
| CVE-2026-32597 (PyJWT) | same crit-ignored defect | RFC 8725 §3.5 | internal/jose.TestParseSigned_CritHeaderRejectedAtVerify |
| CVE-2024-29371 (jose4j JWE decompression bomb) | resource exhaustion via crafted JWE | RFC 8725 §3.11 | internal/jose.FuzzJOSEParse (oversize seed)internal/parendpoint.FuzzPARRequestObjectinternal/introspectendpoint.FuzzIntrospectTokeninternal/revokeendpoint.FuzzRevokeToken |
Authorize / redirect_uri
| CVE | Class | RFC anchor | Test |
|---|---|---|---|
| CVE-2024-10318 (NGINX OIDC reference) | front-channel id_token issued without nonce binding → session fixation | OIDC Core §15.5.2 / RFC 9700 §2.1.2 | internal/authorize.TestRequest_Validate_RejectsImplicitAndHybridResponseTypes (response_type=code only)internal/backchannel.TestSignLogoutToken_EmitsRequiredClaims (logout_token typ discrimination) |
| CVE-2024-8883 (Keycloak) | wildcard / suffix bypass of an earlier redirect_uri patch | RFC 6749 §3.1.2.3 / RFC 9700 §4.1 | internal/authorize.TestRequest_Validate_RedirectURIAttackVariants |
| CVE-2020-15234 (ory/fosite) | case-variant redirect_uri matched a case-different registration | RFC 6749 §3.1.2.3 | internal/authorize.TestRequest_Validate_RedirectURIAttackVariants |
| GHSA-rfq3-w54c-f9q5 (ory/fosite) | loopback redirect rule allowed host / query override; fix narrows runtime variation to the port only — exact-string match here is even stricter | RFC 6749 §3.1.2.3 / RFC 9700 §4.1 | internal/authorize.TestRequest_Validate_RedirectURIAttackVariants |
PKCE / code exchange
| CVE | Class | RFC anchor | Test |
|---|---|---|---|
| CVE-2024-23647 (authentik ≤2023.10.6, CVSS 6.1) | /token accepted code_verifier on codes minted without a code_challenge — PKCE downgrade | RFC 9700 §4.8 / RFC 7636 §4.6 | internal/grants/authcode.TestExchange_NoPKCE_RejectsSmuggledVerifier |
| CVE-2025-4144 (Cloudflare workers-oauth-provider <0.0.5, CVSS 8.1) | same downgrade variant in a different ecosystem | RFC 9700 §4.8 | internal/grants/authcode.TestExchange_NoPKCE_RejectsSmuggledVerifier |
Authorization code interception (cross-client retrieval)
| CVE | Class | RFC anchor | Test |
|---|---|---|---|
| GHSA-vh7g-p26c-j2cw (dexidp/dex, 2024) | back-channel ID-token retrieval after authorization-code interception — redeeming the code under a different client_id returned tokens minted for the victim. Structural mitigation: the (code, client_id, redirect_uri[, code_verifier]) tuple must match at exchange | RFC 6749 §4.1.3 / OIDC Core §3.1.3.4 | internal/grants/authcode.TestExchange_RejectsClientMismatch |
Client authentication / private_key_jwt
| CVE | Class | RFC anchor | Test |
|---|---|---|---|
| CVE-2025-27370 (OIDF coordinated, OIDC) | private_key_jwt aud confusion: malicious AS could relay a key reused across ASs and impersonate the client | RFC 7523bis / FAPI 2.0 §5.2.2 | internal/clientauth.TestPrivateKeyJWTVerifier_AudIssuer_AcceptedViaAuxAudiences |
| CVE-2025-27371 (IETF coordinated, OAuth 2.0) | same defect, OAuth profile lineage | RFC 7523bis | internal/clientauth.TestPrivateKeyJWTVerifier_AudIssuer_AcceptedViaAuxAudiences |
| CVE-2020-15222 (ory/fosite < 0.31.0, GHSA-mh3m-8c74-74xh) | private_key_jwt jti uniqueness not enforced — assertion replay | RFC 7523 §3 / CWE-345 | internal/clientauth.TestPrivateKeyJWTVerifier_JTIReplay_Rejected |
| GHSA-v3q9-2p3m-7g43 (ory/fosite, 2020 cluster) | same jti-replay defect class re-disclosed under a separate GHSA — structural mitigation is identical (per-jti single-use within the assertion's exp window) | RFC 7523 §3 / CWE-345 | internal/clientauth.TestPrivateKeyJWTVerifier_JTIReplay_Rejected |
Session lifecycle (fixation / rotation)
| CVE | Class | RFC anchor | Test |
|---|---|---|---|
| GHSA-xhpr-465j-7p9q (Keycloak, 2024) | first-login phishing via email verification (CWE-384 session fixation) — a session that pre-existed the trust transition continued to be authoritative after verification, letting an attacker who planted the cookie ride the post-verification trust. Structural mitigation: rotate session ID on the trust boundary, but preserve CreatedAt so an attacker cannot extend lifetime by triggering rotation | OIDC Core §3.1.2.7 | internal/sessions.TestManager_Rotate_IssuesFreshIDPreservingChooserGroupinternal/sessions.TestManager_Rotate_PreservesCreatedAt |
Multi-factor authentication (TOTP / step-up)
| CVE | Class | RFC anchor | Test |
|---|---|---|---|
| GHSA-9r3w-4j8q-pw98 (cal.com) | providing a TOTP code skipped the password check entirely — TOTP step ran without primary-factor proof | RFC 6238 / OIDC Core §2 (acr semantics) | internal/authn.TestLoginFlowTOTPRequiresPrimary (orchestrator gate)internal/authn/totp.TestAuthenticator_BeginRequiresSubjectinternal/authn/totp.TestAuthenticator_ContinueRequiresSubject (adapter gate) |
| GHSA-5jfq-x6xp-7rw2 (Keycloak) | second-factor bypass — same structural class, covered by the same two-layer mitigation (orchestrator step ordering + adapter Subject-required gate) | RFC 6238 / OIDC Core §2 | (same tests as above) |
JARM / response signing
| CVE | Class | RFC anchor | Test |
|---|---|---|---|
| CVE-2023-6927 (Keycloak) | response_mode=form_post.jwt bypass of CVE-2023-6134 — JARM added without the same alg restrictions as the bearer flow | FAPI 2.0 Message Signing §5.4 / RFC 8725 §3.1 | internal/jarm.TestSigner_AlgIsES256_Structural |
| CVE-2023-6134 (Keycloak, parent) | original form-post downgrade; tracked via 6927 | RFC 8725 §3.1 | internal/jarm.TestSigner_AlgIsES256_Structural |
Error response surfaces (redirect / form_post)
The authorize endpoint emits errors over two surfaces — a redirect with query parameters and an auto-submitting form_post HTML page. Both must escape RP-supplied bytes so a hostile redirect_uri or error_description cannot inject markup or open-redirect chains.
| CVE | Class | RFC anchor | Test |
|---|---|---|---|
| GHSA-27gc-wj6x-9w55 (Keycloak, 2024) | error_description reflected into HTML error pages without escaping (CWE-79 / CWE-601) — phishing / open-redirect chains. Two-layer mitigation: (1) error_description is a closed catalogue of hardcoded sentinels — RP bytes never reach the field directly; (2) on the wire, url.Values.Encode percent-encodes the redirect surface and html.EscapeString escapes both action= and value= on the form_post surface | RFC 6749 §4.1.2.1 / RFC 9700 §4.10 | internal/jarm.TestWriteFormPost_EscapesRedirectAndJWTinternal/authorizeendpoint.TestBuildRedirectError_EncodesHostileBytes_NoXSSinternal/authorizeendpoint.TestBuildRedirectError_StripsControlBytes |
Operator observability (silent failure on revoke)
| CVE | Class | RFC anchor | Test |
|---|---|---|---|
| GHSA-7mqr-2v3q-v2wm (ory/fosite) | /revoke silently swallowed storage errors — RFC 7009 §2.2 still requires a wire 200, but operators had no observable signal that revocation actually failed. The library keeps the wire 200 and additionally emits token.revoke_failed on every non-NotFound store fault so SOC tooling can detect the silent-failure class | RFC 7009 §2.2 | internal/revokeendpoint.TestHandler_RefreshToken_StoreFault_EmitsAudit |
DoS / parsing safety
Fuzz harnesses across the JOSE / endpoint surface keep parsing panic-free against crafted inputs:
| Surface | Fuzzer | CVE class kept out |
|---|---|---|
| JOSE parse | internal/jose.FuzzJOSEParse | RFC 8725 §3.11 / CVE-2024-29371 (decompression bomb), 2015 alg=none cluster |
| PAR request object | internal/parendpoint.FuzzPARRequestObject | CVE-2024-29371 (CVSS 7.5; jose4j JWE decompression bomb) |
| Introspection token | internal/introspectendpoint.FuzzIntrospectToken | CVE-2024-29371 |
| Revocation token | internal/revokeendpoint.FuzzRevokeToken | RFC 8725 §3.11 / CVE-2024-29371 (panic immunity) |
The same FuzzJOSEParse no-panic + JWS-only contract additionally class-covers a cluster of dependency-side advisories that exercise input shapes the OP never accepts (compact JWS only, JWE / compression paths absent, CBC-mode JWE algs not in the allowlist):
| Advisory | Source | Class-coverage |
|---|---|---|
| GHSA-78h2-9frx-2jm8 | go-jose | JWE decryption panic — ParseSigned is JWS-only and never enters the JWE decrypt path |
| GHSA-c6gw-w398-hv78 | go-jose | parse DoS on pathological JSON — covered by the no-panic fuzz contract |
| GHSA-c5q2-7r4c-mv6g | go-jose | compression amplification (CVE-2024-29371 cluster) — compact JWS only, no compression path |
| GHSA-pvcr-v8j8-j5q3 | lestrrat-go/jwx | JSON-form parse panic — compact-only rejection |
| GHSA-hj3v-m684-v259 | lestrrat-go/jwx | JWE compression DoS — same compact-only contract |
| GHSA-7f9x-gw85-8grf | lestrrat-go/jwx | malicious JWE-params DoS — same compact-only contract |
| GHSA-rm8v-mxj3-5rmq | lestrrat-go/jwx | CBC-mode JWE padding-oracle possibility — JWS-only allowlist (RS256 / PS256 / ES256 / EdDSA) excludes every CBC-mode JWE alg |
What this list deliberately does not include
- CVEs against this library. The library is pre-v1.0 and has no published CVE record yet; if one is filed, it goes in
SECURITY.mdand through the disclosure flow on Reporting a security issue, not here. - Dependency defects whose trigger inputs the OP's input contract does NOT structurally reject. Those are tracked through
govulncheckin CI and resolved by version bump. Where the OP's compact-JWS-only / JWS-only-allowlist contract structurally rejects the trigger inputs (e.g. JWE-side panics, CBC padding oracles), the advisory IS listed in the table above with a "class-covered" pointer to the fuzz harness. - TLS / transport defects (e.g.
GHSA-gr79-9v6v-gc9r,GHSA-q8hq-4h99-fj7x). The library does not own its HTTP server; TLS configuration is the embedder's responsibility. See Library posture. - SAML defects (e.g.
GHSA-m9hp-7r99-94h5). SAML is not implemented; this is an OP only. - Theoretical attacks without a published CVE. A test motivated purely by a spec section (e.g. RFC 8725 §3.x) is still in the codebase, but won't appear here unless a CVE pins the class to a named defect somewhere in the ecosystem.
Reading the bigger picture
The CVE-driven tests sit alongside three other layers of regression material:
- Spec scenarios —
tests/scenarios/(in the repo) catalogues OIDC / OAuth / FAPI behaviours from the spec text directly, regardless of whether a CVE exists. - OFCS conformance harness — see OFCS conformance status. The OpenID Foundation's certified test suite drives the public surface end-to-end against the FAPI 2.0 plans.
- Fuzz harnesses — listed above, run on every PR.
If you find a CVE class this library should pin and doesn't, please open an issue or follow the disclosure flow for anything that would itself be a vulnerability to discuss in public.