Summary
A configuration-dependent authentication bypass in Better Auth can cause an OAuth sign-in state to be accepted as a Magic Link token.
An unauthenticated attacker may obtain a session for an existing user or create an incorrectly email-verified account when specific Magic Link, OAuth, and database-backed state settings are enabled.
A configuration-dependent authentication bypass in Better Auth can cause an OAuth sign-in state to be accepted as a Magic Link token.
An unauthenticated attacker may obtain a session for an existing user or create an incorrectly email-verified account when specific Magic Link, OAuth, and database-backed state settings are enabled.
Affected context
The issue occurs in Better Auth deployments using Magic Link alongside a built-in social or Generic OAuth provider. Risk is present when Magic Link token storage and global verification identifier settings cause OAuth state and Magic Link records to use the same stored identifier, while OAuth state is persisted with the database strategy. The impact depends on enabled sign-up behavior and the existence of a targeted email address.
The issue occurs in Better Auth deployments using Magic Link alongside a built-in social or Generic OAuth provider. Risk is present when Magic Link token storage and global verification identifier settings cause OAuth state and Magic Link records to use the same stored identifier, while OAuth state is persisted with the database strategy. The impact depends on enabled sign-up behavior and the existence of a targeted email address.
Exploit preconditions
- Attack surface: Better Auth authentication endpoints handling Magic Link verification and OAuth sign-in
- Required access: No prior authentication or mailbox access; the attacker needs a known target email address
- Trigger point: Processing an OAuth sign-in state through the Magic Link verification flow
- Required configuration: Magic Link enabled with
storeTokenset toplain, or set tohashedwhileverification.storeIdentifieris alsohashed; a built-in social or Generic OAuth provider enabled; andaccount.storeStateStrategyset todatabase - Why exploitation is possible: The configured storage and identifier behavior can make OAuth state and Magic Link verification records resolve to the same stored identifier
- Attack surface: Better Auth authentication endpoints handling Magic Link verification and OAuth sign-in
- Required access: No prior authentication or mailbox access; the attacker needs a known target email address
- Trigger point: Processing an OAuth sign-in state through the Magic Link verification flow
- Required configuration: Magic Link enabled with
storeTokenset toplain, or set tohashedwhileverification.storeIdentifieris alsohashed; a built-in social or Generic OAuth provider enabled; andaccount.storeStateStrategyset todatabase - Why exploitation is possible: The configured storage and identifier behavior can make OAuth state and Magic Link verification records resolve to the same stored identifier
Why this happens
The underlying bug is an authentication-state separation failure. Under certain combinations of storage and hashing settings, values created for OAuth transaction state can be interpreted as Magic Link verification credentials. This allows one authentication mechanism to satisfy the trust requirements of another, mapping to CWE-287: Improper Authentication. The insecure pattern is reusing or ambiguously resolving security-sensitive identifiers across independent authentication flows without enforcing type, purpose, and protocol context.
The underlying bug is an authentication-state separation failure. Under certain combinations of storage and hashing settings, values created for OAuth transaction state can be interpreted as Magic Link verification credentials. This allows one authentication mechanism to satisfy the trust requirements of another, mapping to CWE-287: Improper Authentication. The insecure pattern is reusing or ambiguously resolving security-sensitive identifiers across independent authentication flows without enforcing type, purpose, and protocol context.
Potential impact
- An attacker could obtain a normal authenticated session for an existing user
- An attacker could bypass the intended mailbox-ownership requirement for Magic Link authentication
- An attacker could create an account incorrectly marked as email verified when registration is enabled
- Account integrity and authorization decisions could be affected
- Downstream application data could be exposed or modified through the obtained session
- An attacker could obtain a normal authenticated session for an existing user
- An attacker could bypass the intended mailbox-ownership requirement for Magic Link authentication
- An attacker could create an account incorrectly marked as email verified when registration is enabled
- Account integrity and authorization decisions could be affected
- Downstream application data could be exposed or modified through the obtained session
General mitigation guidance
Mitigation generally focuses on preserving strict separation between authentication flows and ensuring that security tokens are bound to their intended purpose.
Common defensive patterns include:
- Use distinct, purpose-bound records and identifiers for OAuth state and Magic Link verification
- Reject tokens when their type, flow, audience, or expected lifecycle does not match the consuming endpoint
- Apply consistent, narrowly scoped token storage and hashing semantics across authentication features
- Require explicit mailbox verification before treating an account as email verified
- Limit session privileges and authorization scope until all required identity checks have completed
- Review authentication configuration combinations for cross-flow identifier collisions
Mitigation generally focuses on preserving strict separation between authentication flows and ensuring that security tokens are bound to their intended purpose.
Common defensive patterns include:
- Use distinct, purpose-bound records and identifiers for OAuth state and Magic Link verification
- Reject tokens when their type, flow, audience, or expected lifecycle does not match the consuming endpoint
- Apply consistent, narrowly scoped token storage and hashing semantics across authentication features
- Require explicit mailbox verification before treating an account as email verified
- Limit session privileges and authorization scope until all required identity checks have completed
- Review authentication configuration combinations for cross-flow identifier collisions
How teams detect issues like this
Detection can combine configuration review, code analysis, and runtime monitoring:
- Search configuration and code for shared identifier derivation between OAuth state and Magic Link verification records
- Flag authentication handlers that accept credentials generated by a different protocol or transaction type
- Review token-consumption logic for missing purpose, flow, audience, expiry, or binding checks
- Add policy checks that require unique namespaces for state, verification, and session artifacts
- Monitor for successful Magic Link verification without corresponding mailbox-delivery evidence or expected OAuth callback completion
- Use automated security review tools to identify authentication tokens reused across unrelated flows
Detection can combine configuration review, code analysis, and runtime monitoring:
- Search configuration and code for shared identifier derivation between OAuth state and Magic Link verification records
- Flag authentication handlers that accept credentials generated by a different protocol or transaction type
- Review token-consumption logic for missing purpose, flow, audience, expiry, or binding checks
- Add policy checks that require unique namespaces for state, verification, and session artifacts
- Monitor for successful Magic Link verification without corresponding mailbox-delivery evidence or expected OAuth callback completion
- Use automated security review tools to identify authentication tokens reused across unrelated flows

