GHSA-wxw3-q3m9-c3jr
### Am I affected? Users are affected if all of the following are true: - The application uses `better-auth` at a version below `1.6.2` (or `@better-auth/sso` paired with such a version). - `betterAuth({ account: { storeStateStrategy } })` is set to `"cookie"`. The default `"database"` is not affected. - The application wires at least one OAuth provider through `genericOAuth({ config })` with `pkce: false`, or it supplies a custom `getToken` or `tokenUrl` that does not require the stored `codeVerifier`. Stock social providers with PKCE on are not affected. - The provider returns arbitrary `code` values to the configured callback URL. If users are on `[email protected]` or later, they are not affected. Fix: 1. Upgrade to `[email protected]` or later (current stable is `1.6.10`). 2. If users cannot upgrade, see workarounds below. ### Summary In `parseGenericState`, the cookie branch decrypted the `oauth_state` cookie and validated expiry, but did not compare the incoming OAuth `state` query parameter to the nonce that `generateGenericState` issued at sign-in. Any callback to `/api/auth/oauth2/callback/<providerId>` that arrived with a forged `state` and any `code` was therefore accepted as long as the browser still held a live `oauth_state` cookie. With `pkce: false` (or any `getToken` path that does not enforce a code-verifier round-trip), an attacker who forced the victim to deliver an attacker-controlled authorization code to the callback would mint a session bound to the attacker's external identity in the victim's browser. Account-linking flows behaved the same way, binding the attacker's external account to an authenticated victim row. ### Details The cookie branch of `parseGenericState` did not compare the cookie's stored nonce to the incoming `state` parameter. The database branch (the default) was not affected because the verification row is keyed by `state` and the lookup itself enforces equality. The fix re-binds the cookie to the nonce: `generate
Properties
- ghsa_id
- GHSA-wxw3-q3m9-c3jr
- severity
- medium
- summary
- Better Auth: OAuth callback accepts mismatched `state` when cookie-backed state storage is used without PKCE
- cvss_score
- 5.3
- cve_id
- GHSA-wxw3-q3m9-c3jr
- cvss_vector
- CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:H/A:N
- is_ghsa_only
- true
- ghsa_published
- 2026-05-15T17:33:40Z
- source_url
- https://github.com/advisories/GHSA-wxw3-q3m9-c3jr
- ghsa_updated
- 2026-05-15T17:33:41Z
Related Entities (6)
VULNERABLE_TO (1)
AFFECTS (1)
HAS_WEAKNESS (3)
REPORTED_BY (1)
Explore deeper with Ninja Signal's threat intelligence graph