GHSA-r4xp-prcw-77qf CVE-2026-110864
better-auth: OAuth Proxy lets an attacker sign in as another user
- Severity
- 9.1 / 10
- Critical · CVSS 4.0
- Exploit chance (EPSS)
- 0.29%
- Chance of exploitation in the next 30 days. Higher than 21.34% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Fix
1.7.7- Upgrade better-auth to this version or later
Description
Am I affected?
You may be affected if you use better-auth from 1.5.0-beta.12 through versions before 1.7.7 with the OAuth Proxy plugin. You are affected only if all of these are also true:
- On a participating environment, the OAuth Proxy plugin has no dedicated
secret, or itssecretequals that environment's global Better Auth secret. - Sign-in state is stored in a cookie (
account.storeStateStrategy: "cookie"). With a database or secondary storage, this is only the case if you chose it explicitly. - Implicit account linking is on (the default).
You are not affected by this path if every participating environment uses a proxy secret distinct from its global Better Auth secret, if sign-in state is stored in the database, or if you use a version before 1.5.0-beta.12.
Summary
The OAuth Proxy plugin trusts any user profile it can decrypt. In the affected setup, Better Auth encrypts sign-in state, including data the caller chose, with the same secret and hands it to anyone who starts a social sign-in. An attacker can use this to get a fake profile for another user's email address that the proxy accepts as real.
Impact
An attacker without an account who knows a user's verified email address can sign in as that user, with that user's permissions. They can read private data, change the account, and link a provider account of their choice to it. They need no provider sign-in and no action from the victim. No availability impact is established, and a reported open redirect was not confirmed.
Patches
The fix is merged for the planned better-auth 1.7.7 release. That package is not available yet.
Upgrade all nodes handling the same cookie-backed OAuth or SAML state flow and all OAuth Proxy participants together, including the production coordinator and preview or development deployments. Keep installed Better Auth packages released alongside better-auth on the same release version. Restart pending sign-in and account-linking flows; pre-upgrade state cookies and proxy payloads are rejected. Public options and API signatures are unchanged.
Workarounds
Until you upgrade to the fixed release, apply one of these:
- Set one strong OAuth Proxy
secretacross every environment that takes part in the proxy flow, and keep it different from each environment's global Better Auth secret. - Set
account.storeStateStrategy: "database". This is already the default when a database or secondary storage is configured. If Magic Link is also enabled, switching can expose a separate cross-purpose verification-record path in affected releases. Ensure the two flows resolve to distinct stored identifiers; with built-in options, use Magic LinkstoreToken: "hashed"with globalverification.storeIdentifierunset or"plain", or disable Magic Link or both built-in social and Generic OAuth sign-in. - Remove the OAuth Proxy plugin if you do not need it.
Setting account.accountLinking.disableImplicitLinking: true stops this path from taking over an existing account. It does not fix the underlying flaw: the callback can still accept attacker-made data as a provider identity. Apply one of the steps above as well.
Affected versions
npm
| Package | Vulnerable | Fixed in |
|---|---|---|
| better-auth | >= 1.5.0-beta.12, < 1.7.7 |
1.7.7 |
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
better-auth npm → 1.7.7
- npm
npm install better-auth@1.7.7- yarn
yarn add better-auth@1.7.7- pnpm
pnpm add better-auth@1.7.7
Severity breakdown
CVSS 4.0 9.1
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
- Attack vector
- Network
- Attack complexity
- High
- Attack requirements
- Present
- Privileges required
- None
- User interaction
- None
- Confidentiality (vulnerable system)
- High
- Integrity (vulnerable system)
- High
- Availability (vulnerable system)
- None
- Confidentiality (subsequent systems)
- None
- Integrity (subsequent systems)
- None
- Availability (subsequent systems)
- None
- Exploit maturity
- Not defined
- Scope
- X
CVSS 3.1 7.4
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
- Attack vector
- Network
- Attack complexity
- High
- Privileges required
- None
- User interaction
- None
- Scope
- Unchanged
- Confidentiality
- High
- Integrity
- High
- Availability
- None
Weakness
CWE-287: Improper Authentication
When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.
How to prevent it
- Architecture and Design: Use an authentication framework or library such as the OWASP ESAPI Authentication feature.
CWE-345: Insufficient Verification of Data Authenticity
The product does not sufficiently verify the origin or authenticity of data, in a way that causes it to accept invalid data.
References
Packages
Other links
- github.com/better-auth/better-auth/security/advisories/GHSA-r4xp-prcw-77qf
- github.com/better-auth/better-auth/pull/11494
- github.com/better-auth/better-auth/commit/ac54bfd67821a7607533af2059858b12bc54e26a
- github.com/better-auth/better-auth/releases/tag/v1.7.7
- vulncheck.com/advisories/better-auth-1.5.0-beta.12-before-1.7.7-authentication-byp…
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GHSA-965c-763c-88jm better-auth: OAuth state can be used as a Magic Link to sign in as another user | Critical | Also affects better-auth |
| GHSA-44jh-23m7-hpcf @better-auth/drizzle-adapter: Concurrent requests can exceed rate limits on PostgreSQL | Medium | Also affects better-auth |
| GHSA-q84f-53jg-9ppm better-auth: Device login approval does not show the requesting client or permissions | High | Also affects better-auth |
| GHSA-qq9h-g4jm-xgf3 Better Auth: Account takeover via pre-account hijacking on magic-link and email-OTP sign-in | High | Also affects better-auth |
| GHSA-2vg6-77g8-24mp Better Auth: Stale sessions persist after user deletion across admin, anonymous, and SCIM flows | Medium | Also affects better-auth |
| GHSA-7w99-5wm4-3g79 @better-auth/oauth-provider's OAuth authorization-code grant allows concurrent redemption when two token requests race the find-then-delete primitive | High | Also affects better-auth |
| GHSA-392p-2q2v-4372 Better Auth: OAuth refresh-token rotation forks the token family on concurrent redemption | High | Also affects better-auth |
| GHSA-9h47-pqcx-hjr4 Better Auth has insecure cryptographic defaults in oidcProvider: alg=none advertised and plain PKCE accepted by default | Critical | Also affects better-auth |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor