Repository navigation
chore(deps): update dependency better-auth to v1.7.7 [security] - #704
Open
renovate[bot] wants to merge 1 commit into
Open
renovate[bot] wants to merge 1 commit into
renovate[bot] wants to merge 1 commit into
Conversation
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
1.7.6→1.7.7@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-adapterfrom 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-adapter1.6.17 through 1.6.31, and keep rate-limit records in a PostgreSQL database.All of these must be true:
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-adapteris fixed in 1.7.0. Upgrade to 1.7.0 or later.The Drizzle fix is merged for the planned
@better-auth/drizzle-adapter1.7.7 release. That package is not available yet. Upgradebetter-authand the installed Drizzle adapter together when 1.7.7 is available. No database schema or public API migration is required.Workarounds
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:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:NReferences
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-authfrom1.4.0-beta.18through versions before1.7.7with the Magic Link plugin and social or Generic OAuth sign-in.You are affected if all of these are true:
storeToken: "plain", or withstoreToken: "hashed"and globalverification.storeIdentifier: "hashed"(including a hashed default).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-auth1.7.7 release. That package is not available yet.Upgrade
better-authand 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 customverification.storeIdentifier.overridesrules to match themagic-link:andauth-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:
account.storeStateStrategyto"cookie". If you also use OAuth Proxy, first configure one dedicated OAuth Proxysecretacross 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.storeTokento"hashed"and leave globalverification.storeIdentifierunset or set it to"plain". Global identifier hashing does not prevent this issue when Magic Link tokens are also hashed.Setting
disableSignUp: trueon 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:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:NReferences
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-authfrom 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:secret, or itssecretequals that environment's global Better Auth secret.account.storeStateStrategy: "cookie"). With a database or secondary storage, this is only the case if you chose it explicitly.You are not affected by this path if every participating environment uses a proxy
secretdistinct 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-auth1.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-authon 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:
secretacross every environment that takes part in the proxy flow, and keep it different from each environment's global Better Auth secret.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.Setting
account.accountLinking.disableImplicitLinking: truestops 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:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:NReferences
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.7Compare Source
Patch Changes
#11476
4186e36Thanks @bytaesu! - Return CAPTCHA errors with the correct JSON Content-Type header.#11469
8620aa9Thanks @aryan1306! - Return rate limit errors with a JSON Content-Type header.#11491
55cb92eThanks @bytaesu! - Respect social providerdisableSignUpwhen signing in with an ID token.#11375
69defbcThanks @bytaesu! - Refresh the active organization after sign-in when a session hook selects the initial organization.#11494
ac54bfdThanks @gustavovalverde! - Isolate OAuth state cookies and each OAuth Proxy payload with purpose-specific encryption keys. TheoAuthProxyoptions 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
ac54bfdThanks @gustavovalverde! - Magic Link verification now accepts only records issued for Magic Link. MagicLink 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.overridesrules for these flows to match the newmagic-link:andauth-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-authalongside it so participating packages use the same releaseversion.
Updated dependencies [
35d7cd3,07bdf7e]:Configuration
📅 Schedule: (UTC)
🚦 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.
This PR was generated by Mend Renovate. View the repository job log.