Insecure cryptographic defaults in oidcProvider: alg=none advertised and plain PKCE accepted by default
The legacy oidcProvider and mcp plugins in better-auth (before 1.6.11) exhibit two related cryptographic defects documented in a first-party advisory. The OIDC discovery document unconditionally advertises 'none' in id_token_signing_alg_values_supported, allowing algorithm-negotiation downgrade attacks where relying parties that do not pin to a specific signing algorithm may accept unsigned tokens. PKCE plain is enabled by default: the authorize handler accepts code_challenge_method=plain and silently downgrades a missing code_challenge_method to 'plain' before the allowlist check fires, contradicting the discovery document which advertises only S256 and violating RFC 9700 (OAuth 2.1). The advisory provides root cause analysis, patch details (dropping 'none' from algorithm lists, defaulting allowPlainCodeChallengeMethod to false, rejecting code_challenge without code_challenge_method), workarounds for unpatched deployments, and migration guidance to @better-auth/oauth-provider which is unaffected by both defects. Fixed in better-auth@1.6.11.
Research notes
- Root causeThe metadata builders unconditionally inject 'none' into the signing algorithm list, and the authorize handler silently rewrites a missing code_challenge_method to 'plain' before the allowlist check, enabling algorithm downgrade to unsigned tokens and PKCE bypass.
- Technical detailThe discovery document advertises 'none' in id_token_signing_alg_values_supported while the runtime accepts plain PKCE, contradicting the discovery document which advertises only S256. This violates RFC 9700 (OAuth 2.1) which explicitly forbids plain PKCE.
- MitigationFixed in better-auth@1.6.11 by dropping 'none' from algorithm lists, defaulting allowPlainCodeChallengeMethod to false, and rejecting code_challenge without code_challenge_method. The replacement @better-auth/oauth-provider package is unaffected by both defects.