better-auth
- 1.7.10 is the latest, published 15 October 2026.
- 22 security advisories, all fixed.
- 1.x: 167 releases since 23 November 2024, 21 in the last 90 days.
Security advisories
Grouped by the version that fixes them, so one upgrade reads as one step.
Fixed in 1.7.0-beta.10 · 1 advisory
- HIGHBetter Auth: Account takeover via pre-account hijacking on magic-link and email-OTP sign-inGHSA-qq9h-g4jm-xgf3
Fixed in 1.7.0-beta.4 · 1 advisory
Fixed in 1.6.11 · 7 advisories
- CRITICALBetter Auth: OAuth refresh-token replay via missing client authentication on oidc-provider and mcp pluginsGHSA-pw9m-5jxm-xr6h
- HIGH@better-auth/oauth-provider's OAuth authorization-code grant allows concurrent redemption when two token requests race the find-then-delete primitiveGHSA-7w99-5wm4-3g79
- HIGHBetter Auth has insecure cryptographic defaults in oidcProvider: alg=none advertised and plain PKCE accepted by defaultGHSA-9h47-pqcx-hjr4
4 more
- HIGHBetter Auth: Device authorization approve and deny accept any authenticated session while the user code is pendingGHSA-cq3f-vc6p-68fh
- HIGHBetter Auth vulnerable to unauthorized invitation acceptance via unverified email match in organization pluginGHSA-fmh4-wcc4-5jm3
- HIGHBetter Auth has an account takeover issue via OAuth auto-link to unverified pre-registered emailGHSA-g38m-r43w-p2q7
- LOWBetter Auth: Stale sessions persist after user deletion across admin, anonymous, and SCIM flowsGHSA-2vg6-77g8-24mp
Fixed in 1.6.2 · 1 advisory
- MODERATEBetter Auth: OAuth callback accepts mismatched `state` when cookie-backed state storage is used without PKCEGHSA-wxw3-q3m9-c3jr
12 older fixes
Fixed in 1.6.0 · 1 advisory
- HIGHBetter Auth: OAuth refresh-token rotation forks the token family on concurrent redemptionGHSA-392p-2q2v-4372
Fixed in 1.5.0-beta.9 · 1 advisory
Fixed in 1.4.9 · 1 advisory
- CRITICALBetter Auth Has Two-Factor Authentication Bypass via Premature Session Caching (session.cookieCache)GHSA-xg6x-h9c9-2m83
Fixed in 1.4.5 · 1 advisory
Fixed in 1.4.2 · 1 advisory
- HIGHBetter Auth affected by external request basePath modification DoSGHSA-569q-mpph-wgww
Fixed in 1.4.0 · 1 advisory
Fixed in 1.3.26 · 1 advisory
- HIGHBetter Auth: Unauthenticated API key creation through api-key pluginGHSA-99h5-pjcv-gr6v
Fixed in 1.2.10 · 1 advisory
Fixed in 1.1.21 · 1 advisory
- HIGHBetter Auth allows bypassing the trustedOrigins Protection which leads to ATOGHSA-vp58-j275-797x
Fixed in 1.1.20 · 1 advisory
- MODERATEBeter Auth has an Open Redirect via Scheme-Less Callback ParameterGHSA-hjpm-7mrm-26w8
Fixed in 1.1.16 · 1 advisory
- MODERATEBetter Auth URL parameter HTML Injection (Reflected Cross-Site scripting)GHSA-9x4v-xfq5-m8x5
Fixed in 1.1.6 · 1 advisory
- HIGHBetter Auth has an Open Redirect Vulnerability in Verify Email EndpointGHSA-8jhw-6pjj-8723
Releases in the last 90 days
Feed of releases and advisoriesEvery stable release, newest first. Notes are quoted as the maintainers published them.
1.7.10
15 October 2026Fixed Captcha and OpenAPI plugin subpath imports and type resolution for better-auth/plugins/multi-session and better-auth/test.
Section of a shared release note
better-authBug Fixes
Fixed Captcha and OpenAPI plugin subpath imports and type resolution for
better-auth/plugins/multi-sessionandbetter-auth/test.Fixed Google One Tap sign-ins not recording
googleas the last login method.Fixed imports from
better-auth/plugins/one-tapfailing with a not-exported error.Fixed Google One Tap ignoring plugin-level
autoSelectandcancelOnTapOutsidesettings.Fixed Google One Tap sign-ins ignoring configured Google profile mapping and user info updates.
Fixed Google One Tap calling a prompt method unsupported by FedCM and retrying skipped prompts.
For detailed changes, see
CHANGELOG1.7.9
15 October 2026Fixed onAPIError.onError handlers to finish before responses are sent and log failures without interrupting requests
Section of a shared release note
better-authBug Fixes
Fixed
onAPIError.onErrorhandlers to finish before responses are sent and log failures without interrupting requests
For detailed changes, see
CHANGELOG1.7.8
14 October 2026Aligned cookie security attributes with RFC 6265bis
Section of a shared release note
better-authBug Fixes
- security
Aligned cookie security attributes with RFC 6265bis
Added SvelteKit 3 to the supported peer dependency range
Fixed stale cookies persisting after
customSessionsessions expire or are revokedFixed
customSessiontreating session lookup errors as signed-out usersFixed sign-in failures, replay checks, and SIWE email handling with
generateId: "uuid"Removed non-returned custom fields from inferred output schema types
Fixed Kysely migration foreign keys when custom table names match another model key
Reduced organization plugin server bundles by excluding unused Zod locales
Aligned
@better-auth/utilsandbetter-calldependency versions across official packagesFixed generic OAuth providers remaining unavailable after discovery fails at startup by retrying on subsequent requests
Fixed
lastLoginMethodsign-in failures whencookieNameormaxAgeis explicitlyundefinedFixed magic link verification changing percent-encoded characters in callback URLs
Fixed type errors when using
oauthProvider()ormcp()withexactOptionalPropertyTypesFixed organization plugin type errors in projects with
skipLibCheck: falseFixed failed password resets consuming reset links or OTPs before the new password is saved
Fixed password resets and changes retaining the new password when database session revocation fails
Fixed phone number password resets to use a configured
verifyOTPcallbackFixed secondary-storage session failures leaving sign-ups, passkey registrations, or SSO sign-ins in an inconsistent state
Fixed missing device sessions and failed automatic session switching after cache eviction
For detailed changes, see
CHANGELOG- security
1.7.7
30 September 2026Fixed a critical Magic Link account-takeover vulnerability.
Section of a shared release note
better-authMagic Link upgrade: Upgrade servers sharing verification storage together, request new Magic Links, and restart pending OAuth/SAML sign-ins. No database migration is required. See the critical advisory for affected configurations and custom storage changes.
Bug Fixes
- security
Fixed a critical Magic Link account-takeover vulnerability.
Fixed ID-token sign-in ignoring the social provider’s
disableSignUpsetting.Fixed OAuth Proxy accepting sign-in state as a provider profile. Upgrade all OAuth Proxy participants together; see the OAuth Proxy upgrade guidance.
Fixed CAPTCHA errors missing the JSON
Content-Typeheader.Fixed the active organization failing to refresh after sign-in when a session hook selects the initial organization.
Fixed rate-limit errors missing the JSON
Content-Typeheader.
For detailed changes, see
CHANGELOG- security
1.7.6
24 September 2026Added support for a bannedUserMessage function that receives the banned user, allowing sign-in errors to include details such as the ban reason.
Section of a shared release note
better-authFeatures
Added support for a
bannedUserMessagefunction that receives the banned user, allowing sign-in errors to include details such as the ban reason.Added Vercel BotID as a captcha provider for protected authentication routes.
Bug Fixes
Passwords over
maxPasswordLengthare now rejected withPASSWORD_TOO_LONGbefore hashing or verification.Fixed React hydration mismatches when session or plugin auth queries resolve before streamed components hydrate.
Prevented older auth-query responses from overwriting newer results when requests overlap.
Fixed model identity when a custom model name matches another schema key.
Fixed schema validation for Cloudflare D1 when the Kysely dialect cannot introspect the database.
Fixed social account linking through the OAuth Proxy plugin.
For detailed changes, see
CHANGELOG1.7.5
14 September 2026Added database.schemaName support for direct PostgreSQL connections.
Section of a shared release note
better-authFeatures
Added
database.schemaNamesupport for direct PostgreSQL connections.
Bug Fixes
Improved server-side logging for Cloudflare Turnstile verification failures.
Fixed PostgreSQL migrations incorrectly identifying tables and views across schemas.
Fixed MySQL index validation for existing string columns.
Removed the unused optional
better-sqlite3peer dependency to prevent installation conflicts.
For detailed changes, see
CHANGELOG1.6.33
14 September 2026Fixed database option type inference for projects that do not use Cloudflare Workers.
@better-auth/coreBug Fixes
Fixed database option type inference for projects that do not use Cloudflare Workers.
For detailed changes, see
CHANGELOG1.6.32
14 September 2026Improved diagnostics for Cloudflare Turnstile verification failures
Section of a shared release note
better-authBug Fixes
Improved diagnostics for Cloudflare Turnstile verification failures
For detailed changes, see
CHANGELOG1.7.4
10 September 2026Added experimental.instrumentation.enabled to disable OpenTelemetry span creation per auth instance.
Section of a shared release note
better-authFeatures
Added
experimental.instrumentation.enabledto disable OpenTelemetry span creation per auth instance.Added support for additional session fields in
testUtilsauth helpers.Added Vitest 5 support to the testing utilities.
For detailed changes, see
CHANGELOG1.6.31
10 September 2026Added an option to disable OpenTelemetry span creation for individual auth instances
Section of a shared release note
better-authFeatures
Added an option to disable OpenTelemetry span creation for individual auth instances
For detailed changes, see
CHANGELOG
Show 11 earlier releases
1.7.3
6 September 2026Added Cloudflare as a built-in social provider with client-secret and PKCE support.
Section of a shared release note
better-authFeatures
Added Cloudflare as a built-in social provider with client-secret and PKCE support.
Enabled schema validation during initialization by default, including in production, and rejected authentication requests on detected mismatches.
Added
isPasswordCompromisedfor checking passwords against Have I Been Pwned in custom server-side flows.
Bug Fixes
Aligned generated OpenAPI required fields with runtime validation.
Handled malformed custom-scheme callback URLs without excessive processing.
Improved Auth0 domain normalization to avoid slow trailing-slash processing.
Prevented generic OAuth discovery failures from taking down the authentication API.
Tracked email OTP sign-ins in the last login method plugin.
Fixed callback hooks being skipped after proxied OAuth sign-ins and preserved server state when callback cookies are unavailable. The legacy /oauth-proxy-callback endpoint is deprecated and will be removed in the next minor release.
Fixed
getSessionfailures when cookie caching is disabled and cached session cookies remain.Fixed TOTP re-enrollment replacing an active authenticator and its backup codes.
Prevented duplicate session requests and hydration mismatches in Nuxt
useFetch.Improved dynamic organization role permission check performance.
Added type-safe Nuxt
useFetchintegration for the Vue client'suseSessionhook.Restored compatibility with 1.6 account schemas by identifying accounts with
(providerId, accountId)instead of issuer.
For detailed changes, see
CHANGELOG1.7.2
26 August 2026Fixed permanent user bans to clear expiration dates from previous temporary bans.
Section of a shared release note
better-authBug Fixes
Fixed permanent user bans to clear expiration dates from previous temporary bans.
Fixed client types with more plugins being assignable to types declaring fewer plugins.
Added warnings for invalid signed session data in the cookie cache.
Fixed disabled MyISAM indexes from satisfying migration index checks.
Fixed programmatic migrations on Cloudflare D1 while preserving existing-index validation.
Allowed
~in relative callback URLs validated by trusted-origin checks.Improved validation of relative callback and redirect URLs with paths, queries, and fragments.
Allowed same-origin form submissions with
Referrer-Policy: no-referrerwhile continuing to reject untrusted origins.Improved
getTestInstanceperformance with a faster default password hasher.Standardized built-in placeholder emails to the namespaced
{identifier}@{namespace}.placeholder.invalidformat.
For detailed changes, see
CHANGELOG1.7.1
18 August 2026Added native database transaction support to test instances for PostgreSQL and MySQL.
Section of a shared release note
better-authBug Fixes
Added native database transaction support to test instances for PostgreSQL and MySQL.
Updated bundled dependencies (
jose, nanostores, noble crypto packages, SimpleWebAuthn) to their latest compatible releases, with no changes required to existing projects.
For detailed changes, see
CHANGELOG1.7.0
18 August 2026Moved database joins out of experimental into the stable advanced.database.joins optionMigration: Replace experimental: { joins: true } with advanced: { database: { joins: true } }. Drizzle and Prisma users should regenerate their schema (npx auth@latest generate) so it includes the required relations.
Section of a shared release note
better-authBreaking Changes
- breaking
Moved database joins out of
experimentalinto the stableadvanced.database.joinsoptionMigration: Replace
experimental: { joins: true }withadvanced: { database: { joins: true } }. Drizzle and Prisma users should regenerate their schema (npx auth@latest generate) so it includes the required relations. - breaking
Scoped account identity by trusted issuer, keying accounts on
(issuer, accountId)Migration: Accounts now require
Account.issuer. Read provider identity fromaccountInfo.account.accountId, dropmapping.idfrom SSO configs, and give themicrosoftEntraIdhelper a concrete tenant GUID. Apply the account-identity backfill in the 1.7 upgrade guide before deploying. - breaking
Required captcha endpoint entries to match full auth paths, with wildcard support
Migration: Replace partial paths such as
/sign-inwith explicit wildcards like/sign-in/*or/sign-in/**. - breaking
Moved the MCP plugin into its own
@better-auth/mcppackage built on the OAuth providerMigration: Install
@better-auth/mcpand@better-auth/cimd, add the now-requiredjwt()plugin, and move options nested underoidcConfigto flatmcp({ ... })options. RenamewithMcpAuthtorequireMcpAuthandmcpHandlertocreateMcpProtectedRequestHandler. Regenerate the schema (npx auth migrate):oauthApplicationbecomesoauthClient, plus newoauthRefreshTokenandoauthClientAssertiontables. - breaking
Added OIDC back-channel logout so ending a session cuts off every connected app's API access
Migration: Introspecting an access token whose session has ended now returns
{ active: false }, and/oauth2/userinforejects it. Clients opt into notifications by registeringbackchannel_logout_uri. Run the schema migration for the newoauthClientandoauthAccessTokencolumns. - breaking
Modeled OAuth protected resources explicitly, with per-resource TTLs, scopes, claims, and signing pins
Migration:
validAudiencesis removed: move each resource identifier intoresourcesand link restricted clients throughoauthClientResource.@better-auth/mcpnow requires an explicitresource. Runnpx @better-auth/cli generateand apply the migration before deploying. - breaking
Decoupled SCIM provisioning from the organization plugin
Migration: SCIM configuration, client APIs, database schema, and the Group model are all replaced, and provisioning state cannot migrate in place. Follow the SCIM cutover in the 1.7 upgrade guide, including a full directory reprovision, before resuming traffic.
- breaking
Added OTP-only two-factor enablement with a discriminated
enableTwoFactorresponseMigration:
enableTwoFactornow returns amethodfield ("otp"or"totp"); narrow on it before readingtotpURIandbackupCodes. Passmethod: "otp"for OTP enrollment, which requiresotpOptions.sendOTP. - breaking
Resolved the auth origin from
Hostby default when using a dynamicbaseURLMigration: If your proxy exposes the public hostname only through
x-forwarded-host, setadvanced.trustedProxyHeaders: true. Deployments where the proxy rewritesHost(nginx default, Vercel, Cloudflare, Netlify) are unaffected. - breaking
Added unique lookup indexes for the device authorization
deviceCodeanduserCodecolumnsMigration: Resolve duplicate code values before applying the migration. MySQL and SQL Server installations must also convert both columns to bounded strings and clean up values longer than 191 characters.
- breaking
Enforced S256 PKCE in the Electron sign-in flow and hardened custom-scheme origin checks
Migration: Upgrade the
@better-auth/electronclient and server together and add your app's scheme totrustedOrigins. Thecode_challenge_methodparameter anddisableOriginOverrideoption are removed, and host-bearing custom-scheme entries now match that host exactly. - breaking
Identified Microsoft Entra accounts by the stable
oidclaimMigration: Migrate existing Microsoft account rows created from
subbefore upgrading. Tokens without a validoidare rejected. - breaking
Required a Google client ID before Google One Tap verifies ID tokens
Migration: Configure
oneTap({ clientId })orsocialProviders.google.clientId. - breaking
Removed the deprecated
oidcProviderpluginMigration: Move OIDC authorization-server integrations to
@better-auth/oauth-provider. - breaking
Rewrote the generic OAuth plugin as a first-class social provider with OAuth 2.1 defaults
Migration: Replace
signIn.oauth2({ providerId })withsignIn.social({ provider }),oauth2.link()withlinkSocial(), and dropgenericOAuthClient(). Callbacks move to/api/auth/callback/:id,pkcenow defaults totrue, andissuerandrequireIssuerValidationare removed in favor of OIDC discovery. - breaking
Separated OAuth device grant ownership into
oauthDeviceAuthorization()Migration: The OAuth integration replaces the optional
resourcecolumn withoauthClientIdandresources, so regenerate and apply the schema. Let pending device codes expire before upgrading from an earlier 1.7 prerelease. - breaking
Verified provider
id_tokenswith a single shared verifierMigration: Custom
UpstreamProviderimplementations replace the removedverifyIdTokenmethod with anidTokenconfig carrying a JWKS source, issuer, and audience. PayPal clientid_tokensign-in now returnsID_TOKEN_NOT_SUPPORTED; its redirect flow is unchanged.
Features
Added
clientAssertionsupport to the Microsoft Entra ID social providerMade the
Authinstance directly fetchableAdded per-provider
requireEmailVerificationfor social sign-inAdded a
user.validateUserInfogate for rejecting an identity before a user is created or linkedAdded
hydrateSessionsouseSessionreturns server-fetched data on the first renderAdded compound table indexes to plugin database schemas
Added
allowIdpInitiatedsupport for IdP-initiated flows through a secure server-side bounceAdded RP-initiated logout so
signOut()can also sign users out of the OpenID providerAdded
refreshTokenParamsfor forwarding extra parameters on generic OAuth token refreshVerified discovery
id_tokensagainst the provider JWKS and enabledid_tokensign-in for generic OAuth
- breaking
1.6.30
17 August 2026Fixed concurrent cold-start requests from intermittently losing authentication or transaction context due to an async storage initialization race
Section of a shared release note
better-authBug Fixes
Fixed concurrent cold-start requests from intermittently losing authentication or transaction context due to an async storage initialization race
For detailed changes, see
CHANGELOG1.6.29
14 August 2026Improved deleteSessions performance by running deletes in parallel instead of sequentially
Section of a shared release note
better-authBug Fixes
Improved
deleteSessionsperformance by running deletes in parallel instead of sequentially
For detailed changes, see
CHANGELOG1.6.28
13 August 2026Prevented duplicate session requests during React Suspense retries while preserving revalidation for interrupted refreshes
Section of a shared release note
better-authBug Fixes
Prevented duplicate session requests during React Suspense retries while preserving revalidation for interrupted refreshes
Restored client plugin declaration compatibility for downstream TypeScript consumers
For detailed changes, see the
CHANGELOG.1.6.27
11 August 2026Fixed duplicate session requests being made across Suspense retries
Section of a shared release note
better-authBug Fixes
Fixed duplicate session requests being made across Suspense retries
For detailed changes, see
CHANGELOG1.6.26
4 August 2026Fixed session cleanup on user deletion to also remove sessions from secondary storage
Section of a shared release note
better-authBug Fixes
Fixed session cleanup on user deletion to also remove sessions from secondary storage
Fixed
findSessionsto skip invalid secondary-storage session entries without discarding other valid sessionsFixed email OTP sign-up to pass the verification type to custom OTP generators
Fixed email OTP password reset to allow retrying after entering an invalid password
Fixed email OTP verification to no longer reveal whether an email is registered before the OTP is verified
Fixed
jwtClient()collapsingcreateAuthClienttype inference when combined with other client pluginsFixed JWT key minting inside database transactions to use the transaction-scoped adapter, preventing deadlocks on SQLite and ensuring keys commit with their surrounding transaction on Postgres and MySQL
Fixed
oAuthProxyto preserve Apple user data fromform_postcallbacksFixed
oneTapClient()collapsingcreateAuthClienttype inference when combined with other client pluginsFixed database rate-limit cleanup to complete when no background task handler is configured
Improved
nextCookiesperformance in instrumented Next.js applications by reusing thenext/headersimport promise
For detailed changes, see
CHANGELOG1.6.25
23 July 2026Fixed Apple OAuth not sending the PKCE code challenge during authorization, causing token exchange failures
Section of a shared release note
better-authBug Fixes
Fixed Apple OAuth not sending the PKCE code challenge during authorization, causing token exchange failures
Fixed Google One Tap creating new users when sign-up was disabled on the Google provider
Fixed
$fetchand$storenot being exposed on the Solid clientFixed internal adapter queries being routed to the wrong table when a built-in table's
modelNamewas set to another table's schema key (e.g.user.modelName = "account").
For detailed changes, see
CHANGELOG1.6.24
22 July 2026Added request context (ctx) as a third argument to verifyIdToken, enabling custom ID token verifiers to read request headers
Section of a shared release note
better-authFeatures
Added request context (
ctx) as a third argument toverifyIdToken, enabling custom ID token verifiers to read request headersAdded
beforeStoreCookieoption to the last-login-method plugin for GDPR compliance
Bug Fixes
Replaced flaky MongoDB where-coercion integration test with a direct unit test for more reliable test runs
Fixed the
get-sessionendpoint to includeno-storecache control headers, preventing stale session data from being servedFixed SQLite migration diffs to recognize
BIGINTas a valid number type, preventing spurious pending changes on rate limiter columnsFixed auth requests failing when request cloning throws an error inside verification callbacks
Fixed
useSession({ throw: true })incorrectly excludingnullfrom itsdatatypeFixed auth query revalidation and signal listeners not being restored after a client component remounts
Fixed the
CookieAttributesindex signature type to be more preciseFixed silent misrouting of adapter queries when
user.modelNamewas set to a value that collides with another schema keyFixed Kysely migration generation producing duplicate indexes for fields marked both
uniqueandindexFixed magic-link and email-OTP send endpoints to validate the
Originheader on cookieless requests, preventing cross-origin abuseFixed remote MCP auth 401 challenge headers being hidden from browser clients due to missing CORS exposure
Fixed OpenAPI schema to include plugin user fields (such as
usernameanddisplayUsername) in/sign-up/emailand/update-userrequest bodiesFixed
organization.listMembersfailing with "User not found for member" for organizations with more than ~100 membersFixed organization invitations to use database-generated IDs when
advanced.database.generateIdis configured, matching the behavior of other modelsFixed
getDefaultModelNameto prefer exact schema key matches overmodelNamealiases, preventing adapter queries from being misrouted when a built-in table's name collides with another schema key
For detailed changes, see
CHANGELOG
Major versions
- 1.xsince 23 November 2024 · latest 1.7.10 · 167 releases
- 0.xsince 22 April 2024 · latest 0.8.8 · 61 releases
Quality and security signals
What npm and deps.dev say about the latest release. Signals, not a verdict.
Reading npm and deps.dev…
Registry facts last checked 15 October 2026. Releases and advisories last read 15 October 2026.
Know when your own dependencies move
Inlinr tracks your coding time automatically. Switch dependency tracking on for a project and it reads that repository's manifest to show what is behind and what has been deprecated — off by default, one project at a time.