Skip to content

chore(deps): update dependency better-auth to v1.7.7 [security] - #704

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/npm-better-auth-vulnerability
Open

renovate[bot] wants to merge 1 commit into
mainfrom
renovate/npm-better-auth-vulnerability

Conversation

@renovate

@renovate renovate Bot commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
better-auth (source) 1.7.6 → 1.7.7 age confidence

@​better-auth/drizzle-adapter: Concurrent requests can exceed rate limits on PostgreSQL

CVE-2026-110861 / GHSA-44jh-23m7-hpcf

More information

Details

Am I affected?

You are affected if you use @better-auth/drizzle-adapter from 1.6.17 through versions before 1.7.7 (including the 1.7.0 prereleases from beta.6 through rc.6) or @better-auth/kysely-adapter 1.6.17 through 1.6.31, and keep rate-limit records in a PostgreSQL database.

All of these must be true:

  • Rate limiting is enabled.
  • Rate-limit records are stored in the database.
  • The database is PostgreSQL, used through one of the adapter versions above.

You are not affected if you store rate-limit records in memory (the default) or in secondary storage.

Summary

Database-backed rate limiting on PostgreSQL can let a burst of concurrent requests go over the configured maximum. When many requests arrive at the same time, several of them can pass the limit check together. This weakens the rate limit on password sign-in, two-factor verification, one-time codes, password resets, and other rate-limited endpoints.

Impact

An attacker who sends many requests at once can make more attempts than the application allows.

The issue does not bypass password or one-time-code validation. It does not directly compromise an account. The number of extra attempts is limited by the number of concurrent database connections, the number of application instances, and the rate-limit window.

Patches

@better-auth/kysely-adapter is fixed in 1.7.0. Upgrade to 1.7.0 or later.

The Drizzle fix is merged for the planned @better-auth/drizzle-adapter 1.7.7 release. That package is not available yet. Upgrade better-auth and the installed Drizzle adapter together when 1.7.7 is available. No database schema or public API migration is required.

Workarounds
  • Store rate-limit records in secondary storage.
  • Use a custom rate-limit storage that checks and increments the counter in one atomic step. An atomic step cannot be interrupted by another request.
  • Enforce the intended limit at an upstream layer, such as a reverse proxy or gateway.

In-memory storage also avoids this issue. However, each application instance keeps its own counter, so it may not enforce one shared limit in multi-instance or serverless deployments.

Severity

  • CVSS Score: 3.7 / 10 (Low)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N

References

This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).


better-auth: OAuth state can be used as a Magic Link to sign in as another user

CVE-2026-110862 / CVE-2026-114607 / GHSA-965c-763c-88jm

More information

Details

Am I affected?

You may be affected if you use better-auth from 1.4.0-beta.18 through versions before 1.7.7 with the Magic Link plugin and social or Generic OAuth sign-in.

You are affected if all of these are true:

  • Magic Link is enabled with default storeToken: "plain", or with storeToken: "hashed" and global verification.storeIdentifier: "hashed" (including a hashed default).
  • At least one built-in social provider or Generic OAuth provider is enabled.
  • OAuth state uses account.storeStateStrategy: "database", the default when a database or secondary storage is configured.

Cookie-backed state blocks this path, subject to the OAuth Proxy condition below. With custom hashers, confirm the flows cannot resolve to the same stored identifier.

Summary

Better Auth accepts an OAuth sign-in state value as a Magic Link token. An attacker can start an OAuth sign-in with any email address and use the returned state value to finish a Magic Link sign-in for that address. They never prove that they can read that email.

Impact

An unauthenticated attacker who knows a user's email address can get a normal session for that user, with all of that account's permissions. They need no access to the mailbox, and they do not need to sign in with the OAuth provider or complete an OAuth callback.

If Magic Link sign-up is enabled and no user has the email address, the attacker can instead create an account that Better Auth wrongly marks as email verified, and is signed in to it. The false verified-email flag can also bypass Better Auth's default unproven-account protections when the mailbox owner later signs in, leaving the attacker's session in that account. Applications that trust verified email addresses or email domains may give this account more access, depending on the application.

Patches

The fix is merged for the planned better-auth 1.7.7 release. That package is not available yet.

Upgrade better-auth and installed Better Auth adapters, plugins, and integrations released alongside it together. Upgrade servers sharing verification storage in the same cutover. Request new Magic Links and restart pending OAuth or SAML sign-ins; links and state created before the upgrade cannot complete. Update custom verification.storeIdentifier.overrides rules to match the magic-link: and auth-state: prefixes. There is no user or account data migration, and public token values and API signatures are unchanged.

Workarounds

Until you upgrade to the fixed release, use one of these mitigations:

  • Set account.storeStateStrategy to "cookie". If you also use OAuth Proxy, first configure one dedicated OAuth Proxy secret across all participating environments that differs from each environment's global Better Auth secret. Cookie-backed state can expose a separate OAuth Proxy account-takeover path when the proxy shares the global secret and implicit account linking is enabled.
  • Set the Magic Link plugin option storeToken to "hashed" and leave global verification.storeIdentifier unset or set it to "plain". Global identifier hashing does not prevent this issue when Magic Link tokens are also hashed.
  • Turn off Magic Link sign-in, or turn off social and Generic OAuth sign-in.

Setting disableSignUp: true on the Magic Link plugin is not enough. It only stops the creation of new verified accounts. It does not stop the takeover of existing accounts.

Severity

  • CVSS Score: 9.1 / 10 (Critical)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

References

This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).


better-auth: OAuth Proxy lets an attacker sign in as another user

CVE-2026-110864 / GHSA-r4xp-prcw-77qf

More information

Details

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 its secret equals 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 secret across 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 Link storeToken: "hashed" with global verification.storeIdentifier unset 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.

Severity

  • CVSS Score: 7.4 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N

References

This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).


Release Notes

better-auth/better-auth (better-auth)

v1.7.7

Compare Source

Patch Changes
  • #​11476 4186e36 Thanks @​bytaesu! - Return CAPTCHA errors with the correct JSON Content-Type header.

  • #​11469 8620aa9 Thanks @​aryan1306! - Return rate limit errors with a JSON Content-Type header.

  • #​11491 55cb92e Thanks @​bytaesu! - Respect social provider disableSignUp when signing in with an ID token.

  • #​11375 69defbc Thanks @​bytaesu! - Refresh the active organization after sign-in when a session hook selects the initial organization.

  • #​11494 ac54bfd Thanks @​gustavovalverde! - Isolate OAuth state cookies and each OAuth Proxy payload with purpose-specific encryption keys. The oAuthProxy options and supported configuration remain unchanged.

    Upgrade all Better Auth nodes that handle the same cookie-backed OAuth or SAML relay-state flow together. Upgrade every OAuth Proxy participant, including production and preview or development deployments, in the same cutover. OAuth sign-in, account-linking, and cookie-backed SAML sign-in flows started before the upgrade must be restarted. Mixed old and new participants cannot exchange existing state or proxy payloads, and there is no fallback to the previous shared key.

  • #​11494 ac54bfd Thanks @​gustavovalverde! - Magic Link verification now accepts only records issued for Magic Link. Magic
    Link records and database-backed OAuth or SAML state use separate verification
    identifier prefixes. Links and database-backed sign-ins started before the
    upgrade cannot complete; request new Magic Links and restart those sign-ins.
    Upgrade servers sharing verification storage together, and update
    verification.storeIdentifier.overrides rules for these flows to match the new
    magic-link: and auth-state: prefixes. The link token, callback state,
    endpoints, and public option types are unchanged.

    Upgrade installed Better Auth adapters, plugins, and integrations released
    with better-auth alongside it so participating packages use the same release
    version.

  • Updated dependencies [35d7cd3, 07bdf7e]:


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate Bot added dependencies Pull requests that update a dependency file security labels Oct 27, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file security

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants