Executive Summary
A vulnerability in @better-auth/oauth-provider's OAuth authorization-code grant allows concurrent redemption of authorization codes, potentially leading to multiple independent token sets being issued from a single authorization code. This issue affects users of @better-auth/oauth-provider versions >= 1.6.0, < 1.6.11. The vulnerability has a CVSS score of 7.6.
Technical Analysis
The vulnerability is caused by a non-atomic find-then-delete sequence in the OAuth provider's `POST /oauth2/token` endpoint, on the `authorization_code` grant. This allows two concurrent requests with the same `code` value to both pass the read step before either delete completes, then both proceed to PKCE verification and `createUserTokens`. Each surviving request mints a fresh access token, refresh token, and id token.
How It Gets Exploited
An attacker can exploit this vulnerability by sending two concurrent requests with the same authorization code to the `/api/auth/oauth2/token` endpoint. The requests must be processed before either delete operation completes. The attacker would need to be able to send multiple requests to the endpoint with a short time difference. The first request to arrive takes the row and mints tokens; concurrent racers observe an empty result and return `invalid_grant`.
Impact Assessment
The impact of this vulnerability is that an attacker could potentially obtain multiple independent token sets from a single authorization code. This could allow for unauthorized access to sensitive information or actions. The vulnerability affects users of @better-auth/oauth-provider versions >= 1.6.0, < 1.6.11, or users of the embedded plugin in `better-auth >= 1.4.8-beta.7, < 1.6.0`, or users who enable the legacy `oidc-provider` or `mcp` plugins from `better-auth/plugins`.
Recommended Actions
To mitigate this vulnerability, users should upgrade to `@better-auth/
[email protected]` or later. If developers use the legacy plugin paths from `better-auth/plugins`, they should upgrade `better-auth` to `1.6.11` or later. Alternatively, developers can implement an external mitigation, such as a load-balancer-level idempotency cache keyed by `code`, a database trigger that rejects duplicate token issuance for the same authorization code, or a custom adapter override that performs an atomic compare-and-delete.
Sources
- GitHub Security Advisories
- CVE-2026-53518