fix(deps): update dependency better-auth to v1.4.5 [security]
Note: This PR body was truncated due to platform limits.
This PR contains the following updates:
| Package | Change | Age | Confidence |
|---|---|---|---|
| better-auth (source) | 1.1.10 -> 1.4.5 |
GitHub Vulnerability Alerts
GHSA-9x4v-xfq5-m8x5
Summary
The better-auth /api/auth/error page was vulnerable to HTML injection, resulting in a reflected cross-site scripting (XSS) vulnerability.
Details
The value of error URL parameter was reflected as HTML on the error page: https://github.com/better-auth/better-auth/blob/05ada0b79dbcac93cc04ceb79b23ca598d07830c/packages/better-auth/src/api/routes/error.ts#L81
Impact
An attacker who exploited this vulnerability by coercing a user to visit a specially-crafted URL could execute arbitrary JavaScript in the context of the user's browser.
CVE-2025-27143
Summary
The application is vulnerable to an open redirect due to improper validation of the callbackURL parameter in the email verification endpoint and any other endpoint that accepts callback url. While the server blocks fully qualified URLs (e.g., https://evil.com), it incorrectly allows scheme-less URLs (e.g., //malicious-site.com). This results in the browser interpreting the URL as https://malicious-site.com, leading to unintended redirection.
bypass for : https://github.com/better-auth/better-auth/security/advisories/GHSA-8jhw-6pjj-8723
Affected Versions
All versions prior to 1.1.19
Details
The application’s email verification endpoint (/auth/verify-email) accepts a callbackURL parameter intended to redirect users after successful email verification. While the server correctly blocks fully qualified external URLs (e.g., https://evil.com), it improperly allows scheme-less URLs (e.g., //malicious-site.com). This issue occurs because browsers interpret //malicious-site.com as https://malicious-site.com, leading to an open redirect vulnerability.
An attacker can exploit this flaw by crafting a malicious verification link and tricking users into clicking it. Upon successful email verification, the user will be automatically redirected to the attacker's website, which can be used for phishing, malware distribution, or stealing sensitive authentication tokens.
Impact
Phishing & Credential Theft – Attackers can redirect users to a fake login page, tricking them into entering sensitive credentials, which can then be stolen.
Session Hijacking & Token Theft – If used in OAuth flows, an attacker could redirect authentication tokens to their own domain, leading to account takeover.
GHSA-vp58-j275-797x
Summary
A bypass was discovered in the trustedOrigins validation logic—affecting both absolute URL entries and wildcard domain patterns. This flaw allows an attacker to construct a malicious callbackURL that passes origin checks and triggers an open redirect.
Because redirect endpoints include sensitive tokens (such as password-reset tokens), this vulnerability can enable one-click account takeover if a victim clicks a crafted link.
CVE-2025-53535
Summary
An open redirect has been found in the originCheck middleware function, which affects the following routes: /verify-email, /reset-password/:token, /delete-user/callback, /magic-link/verify, /oauth-proxy-callback.
Details
In the matchesPattern function, url.startsWith( can be deceived with a url that starts with one of the trustedOrigins.
const matchesPattern = (url: string, pattern: string): boolean => {
if (url.startsWith("/")) {
return false;
}
if (pattern.includes("*")) {
return wildcardMatch(pattern)(getHost(url));
}
return url.startsWith(pattern);
};
Open Redirect PoCs
export const auth = betterAuth({
baseURL: 'http://localhost:3000',
trustedOrigins: [
"http://trusted.com"
],
emailAndPassword: {
...
},
})
/reset-password/:token
/verify-email
/delete-user/callback
/magic-link/verify
/oauth-proxy-callback
Impact
Untrusted open redirects in various routes.
CVE-2025-61928
Summary
A critical authentication bypass was identified in the API key creation and update endpoints. An attacker could create or modify API keys for arbitrary users by supplying a victim’s user ID in the request body. Due to a flaw in how the authenticated user was derived, the endpoints could treat attacker-controlled input as an authenticated user object under certain conditions.
Details
The vulnerability originated from fallback logic used when determining the current user. When no session was present, the handler incorrectly allowed request-body data to populate the user context used for authorization decisions. Because server-side validation only executed when authentication was required, privileged fields were not properly protected. As a result, the API accepted unauthenticated requests that targeted other users.
This same pattern affected both the API key creation and update routes.
Impact
Unauthenticated attackers could generate or modify API keys belonging to any user. This granted full authenticated access as the targeted user and, depending on the user’s privileges, could lead to account compromise, access to sensitive data, or broader application takeover.
GHSA-569q-mpph-wgww
Summary
Affected versions of Better Auth allow an external request to configure baseURL when it isn’t defined through any other means. This can be abused to poison the router’s base path, causing all routes to return 404 for all users.
This issue is only exploitable when baseURL is not explicitly configured (e.g., BETTER_AUTH_URL is missing) and the attacker is able to make the very first request to the server after startup. In properly configured environments or typical managed hosting platforms, this fallback behavior cannot be reached.
Details
A combination of X-Forwarded-Host and X-Forwarded-Proto is implicitly trusted. This allows the first request to configure baseURL whenever it is not explicitly configured.
Here's the code that reads the headers:
Here's the call to getBaseURL(), the result is assigned to ctx.baseURL.
Here's the router receiving the poisoned basePath:
X-Forwarded-Host and X-Forwarded-Proto can be used to modify the pathname of a parsed URL object which forms baseURL. basePath is then derived from the pathname of baseURL. Once the router basePath is poisoned it fails to match & route incoming requests.
Repro
Start a better-auth server with no baseURL configuration.
Send the following request as the first request to the server:
curl -i --location 'https://example.com/api/auth/ok' \
--header 'X-Forwarded-Proto: some:' \
--header 'X-Forwarded-Host: junk'
The better-auth API check endpoint returns 404.
Now send a regular request without the X-Forwarded-Proto and X-Forwarded-Host headers.
curl -i --location 'https://example.com/api/auth/ok'
The better-auth API check endpoint still returns 404.
Example result
We have modified the basePath for the router until the server is restarted. An attacker can repeatedly send these attack requests aiming to persistently exploit the vulnerability.
GHSA-x732-6j76-qmhm
Summary
An issue in the underlying router library rou3 can cause /path and //path to be treated as identical routes. If your environment does not normalize incoming URLs (e.g., by collapsing multiple slashes), this can allow bypasses of disabledPaths and path-based rate limits.
Details
Better Auth uses better-call, which internally relies on rou3 for routing. Affected versions of rou3 normalize paths by removing empty segments. As a result:
/sign-in/email//sign-in/email///sign-in/email
…all resolve to the same route.
Some production setups automatically collapse multiple slashes. This includes:
- Vercel with Nextjs (default)
- Cloudflare - when normalize to urls origin is enabled (https://developers.cloudflare.com/rules/normalization/settings/#normalize-urls-to-origin)
In these environments and other configurations where //path reach Better Auth as /path, the issue does not apply.
Fix
Updating rou3 to the latest version resolves the issue:
- better-call previously depended on
"rou3": "^0.5.1" - The fix was introduced after that version (commit: https://github.com/h3js/rou3/commit/f60b43fa648399534507c9ac7db36d705b8874c3)
Better Auth recommends:
- Upgrading to Better Auth v1.4.5 or later, which includes the updated rou3.
- Ensuring the proxy normalizes URLs.
- If project maintainers cannot upgrade yet, they can protect their app by normalizing url before it reaches better-auth handler. See example below:
const req = new Request(...) // this would be the actual request object
const url = new URL(req.url);
const normalizedPath = url.pathname.replace(/\/+/g, "/");
if (url.pathname !== normalizedPath) {
url.pathname = normalizedPath;
// Update the raw request pathname
Object.defineProperty(req, "url", {
value: url.toString(),
writable: true,
configurable: true,
});
}
Impact
- Bypass
disabledPaths - Bypass path-based rate limits
The impact of bypassing disabled paths could vary based on a project's configuration.
Release Notes
better-auth/better-auth (better-auth)
v1.4.5
v1.4.4
🚀 Features
- cli: Better-auth-command - by @Ridhim-RR in #6362 (5e06f)
- scim: Add support to parse custom scim+json media type - by @jonathansamines in #6365 (6e9ec)
🐞 Bug Fixes
- Customizing fields should be optional for rate limit options - by @ceolinwill in #6398 (115c9)
- Chunk account data cookie when exceeding limit - by @jslno in #6393 (c9eca)
- Remove applying user-agent by default - by @Bekacru in #6417 (34d7d)
- Additional fields default values should apply when creating session - by @Bekacru in #5763 (d5713)
- Return null early if userid isn't defined - by @Bekacru in #6418 (e4508)
- logger: Log level priority - by @danielfinke in #6411 (4c25b)
- mcp: Return origin url as authorization server - by @jslno in #6397 (594bb)
- multi-session: Endpoints breaks with invalid signatures - by @ping-maxwell in #6342 (9433e)
- oidc-provider: Resolve getSignedCookie return type - by @bytaesu in #6346 (425dd)
View changes on GitHub
v1.4.3
🚀 Features
- Add Vercel as OAuth provider - by @anatrajkovska in #6316 (6fd02)
- Add support for trusted proxy headers in base URL inference - by @Bekacru and Copilot in #6285 (c4c0b)
🐞 Bug Fixes
- Support @tanstack/solid-start in tanstackStartCookies plugin " - by @Bekacru in #6235 (781d7)
- open-api: Clean up incorrect null type in OpenAPI - by @bytaesu in #6293 (f9cba)
- two-factor: Remove incorrect blocking logic in OTP setup and verification - by @isaacriehm in #6322 (e75d2)
View changes on GitHub
v1.4.2
🚀 Features
- cli: Check
/authforauth.ts- by @ping-maxwell in #6273 (53a74) - github: Add PKCE support for Github - by @Shridhad in #6276 (deb62)
- jwt: Allow custom jwks endpoint - by @luist18 in #6269 (1c45f)
🐞 Bug Fixes
- Support @tanstack/solid-start in tanstackStartCookies plugin - by @jakst in #6235 (c69b3)
- SignIn/signUp API returns user additional field - by @himself65 in #6287 (5ea36)
- cli:
- Kysely migration fails due to chaining addIndex and addColumn on the same alterTable builder - by @ping-maxwell in #6214 (b8a73)
- Prevent duplicate index creation in Prisma schema generation - by @rovertrack in #6234 (0bbd8)
- client:
- email-otp:
- Sign-in email-otp bugs with capitalized emails - by @ping-maxwell in #6237 (fd010)
- oidc-provider:
- organization:
- Have deleteOrganization use adapter.deleteMany instead of delete - by @kefimoto in #6226 (32d3f)
View changes on GitHub
v1.4.1
🚀 Features
- api-key: Support secondary storage - by @ping-maxwell and @Bekacru in #6014 (44308)
🐞 Bug Fixes
- Custom fn field default values should be properly evaluted - by @Bekacru and Copilot in #6212 (590a2)
- jwt: Retrieve latest keys from storage properly - by @Bekacru in #6208 (6aca4)
- passkey: Change
generate-authenticate-optionsfrom POST to GET - by @mburumaxwell in #6199 (f922c)
View changes on GitHub
v1.4.0
🚀 Features
- Bypass transaction with async local storage - by @himself65 in #4711 (52af6)
- Add
returnHeaderstogetSession- by @frectonz in #3983 (19d4b) - Waku integration guide - by @rmarscher in #3990 (3e75a)
- Add support for custom callback for authorization url - by @Bekacru in #4919 (78506)
- Additional fields on account - by @dvanmali in #4935 (bf0ac)
- Add support for custom callback for token url - by @acusti in #5027 (6bb94)
- Enum support for drizzle schema - by @himself65 in #5287 (fd780)
- Nextjs 16 guide - by @Kinfe123 and @himself65 in #5296 (8db97)
- Add
storeStateStrategy- by @himself65 and Copilot in #5470 (b5f3b) - Enhance PostgreSQL support for non-public schema by respecting
search_pathconfiguration - by @okisdev in #5449 (bef33) - Add polar oauth provider - by @ephraimduncan in #5506 (4b075)
- Session store chunking - by @himself65 and Copilot in #5645 (0aa6d)
- Stateless session management - by @Bekacru, Copilot, @ping-maxwell and @himself65 in #5601 (afce9)
- Esm only - by @himself65 in #5703 (b6977)
- Implement automatic server-side IP detection - by @GautamBytes in #5695 (06e8c)
- Async import in
getAdapter- by @himself65 in #5722 (10249) - Improved API error page - by @ping-maxwell and @Bekacru in #5272 (f9964)
- Add request state - by @himself65 in #5742 (cea5b)
- Add support for uuids - by @Bekacru in #5809 (4ac34)
- Auto-index CLI - by @ping-maxwell and @Bekacru in #5357 (af6eb)
- Expose additional http methods - by @jonathansamines and @Bekacru in #5754 (956e2)
better-auth/minimal- by @bytaesu and @Bekacru in #5704 (1ebc6)- Add support for custom response status codes - by @jonathansamines and @Bekacru in #5806 (fa595)
- Support pass raw function as middleware - by @himself65 in #5888 (48a20)
- Support pass raw function as middleware " - by @himself65 in #5888 (a391a)
- Adapter join support - by @ping-maxwell in #5730 (f5bbb)
- Refactor fetch plugins config disableDefaultFetchPlugins to include userAgentPlugin - by @kaandok and @himself65 in #6020 (8e754)
- Utilize database joins across better-auth - by @ping-maxwell in #6004 (e9f5b)
- Support storing account data in a cookie - by @Bekacru in #6013 (06606)
- Adding support for SCIM provisioning - by @jonathansamines in #5685 (ffa29)
- Add support for organization slug on list members - by @Bekacru in #5862 (31a81)
- anonymous:
- captcha:
- cli:
- Add mcp client configs from
cli- by @Kinfe123 and @himself65 in #4872 (70cb4) - Support Cloudflare Workers virtual module imports - by @chhoumann in #5559 (cf050)
- Add mcp client configs from
- client:
- Refetch session when browser state changes - by @himself65 and Copilot in #5630 (522cf)
- Add type helper
AuthClient- by @himself65 in #5815 (7caa2) - Introduce
disableSignalclient option - by @ping-maxwell in #6108 (f4c43)
- core:
- Replace ZodType with
@standard-schema/spec- by @himself65 in #5629 (36315)
- Replace ZodType with
- db:
- Delete hooks - by @Kinfe123 and @himself65 in #4792 (eb76a)
- device-authorization:
- Add verification uri - by @bytaesu and @himself65 in #5451 (8b2b6)
- discord:
- Allow specification of permissions - by @TheUntraceable and @Bekacru in #4717 (69c9b)
- docs:
- email-otp:
- Allow returning undefined in
generateOTP- by @ping-maxwell in #4723 (8ac4f)
- Allow returning undefined in
- expo:
- Support multiple cookie prefixes for better-auth detection - by @himself65 in #6080 (f5285)
- generic-oauth:
- jwt:
- Support custom adapter option for jwt - by @Bekacru in #5812 (10cee)
- Add JWT verification endpoint and refactor verification logic - by @himself65 in #6122 (18cf7)
- Add key rotation - by @Bekacru, Copilot and @Paola3stefania in #6147 (0bd9b)
- last-login-method:
- Update OAuth login method tracking for multiple auth type - by @Kinfe123 in #4693 (5e7b5)
- Add support for 'siwe' as a last login method and added tests - by @rovertrack in #6027 (08316)
- mongodb:
- Support string IDs over ObjectIDs - by @ping-maxwell and @ahmedriad1 in #5384 (0dfe6)
- oauth-proxy:
- oidc-provider:
- Add RP-Initiated Logout endpoint - by @himself65 and Copilot in #6094 (c9085)
- organization:
- Support createdAt on invitations - by @iRoachie and @himself65 in #2346 (fc321)
- Refactor organization schema to use BetterAuth types - by @himself65 in #5515 (a58f1)
- passkey:
- paybin:
- phone-number:
- plugin-openapi:
- Allow passing nonce for CSP - by @GautamBytes in #5751 (fa147)
- prisma:
- Enhance JSON default value handling for arrays and objects in schema generation - by @rovertrack in #5904 (09162)
- session:
- Use JWE for cookie cache by default - by @himself65 in #5510 (f654b)
- sso:
- DefaultSSO options and ACS endpoint - by @Kinfe123 and @Bekacru in #3660 (b3ead)
- Provide default service provider metadata - by @dvanmali in #4866 (e892a)
- Add option to provide login hint - by @tnkuehne and Copilot in #5283 (6f231)
- Add domain verification for SSO providers - by @jonathansamines and @ping-maxwell in #5910 (da965)
- stripe:
🐞 Bug Fixes
- Device authorization plugin - by @bytaesu in #4695 (b9cbd)
- Device authorization plugin - by @bytaesu in #4695 (c3001)
- Reduce any type in generator.ts - by @himself65 in #4710 (0770c)
- Refresh secondary storage sessions on user update - by @frectonz in #4522 (ea89d)
- Allow disable database transaction - by @himself65 in #4733 (a8776)
- Wrap
Math.flooraround the division when calculating TTL - by @DevDuki, Dusan Misic, ping-maxwell and @himself65 in #4768 (14b9e) - Ttl sessions list expiration - by @dvanmali in #3836 (57e04)
- Tests failing due to clock drift - by @dvanmali in #4915 (63ca1)
- Refresh secondary storage sessions on user update - by @frectonz in #4522 (ccc7c)
- Refresh secondary storage sessions on user update - by @frectonz in #4522 (f1b0a)
- Support compressed ipv6 format - by @Velka-DEV in #4982 (d8f11)
- Add required constraint to slug filed in org plugin - by @bytaesu in #4989 (0581a)
- Use consistent messaging on
requestPasswordReset- by @Eazash in #5014 (2f94b) - Cookie size limit shouldn't throw error - by @Bekacru and @himself65 in #5031 (72ecc)
- Handle symbols in proxy get trap to prevent TypeError - by @zbeyens and @himself65 in #4924 (8d46c)
- Ttl for rate limited secondary storage - by @dvanmali in #4961 (f246d)
- Properly encode callback url for email verificaiton - by @Bekacru in #5052 (41d2e)
- Session update database hook should expect partial session type - by @Bekacru in #5056 (ade06)
- Deprecate
options.advanced.generateIdtype - by @himself65 (48249) - Api keys should properly check if a request is from client or server - by @Bekacru (2e236)
- Refactor account deletion functions to trigger database hooks - by @xuchenhao001 in #5114 (dade3)
- Improve username transformation logic - by @ping-maxwell in #5115 (b2a9e)
- Ensure falsy values are valid default values - by @ocherry341 in #5182 (03d62)
- Import
node:async_hooksdirectly - by @himself65 in #5198 (0717e) - Undeclared variable reference on docs - by @Kinfe123 in #5235 (6d6df)
- Argument
whereof type TwoFactorWhereUniqueInput needs at least one ofidarguments - by @AlexStrNik in #5180 (2dab4) - Mobile ai search responsiveness - by @Kinfe123 in #5269 (08d95)
- Type compatibility with
exactOptionalPropertyTypes- by @Kinfe123 and @himself65 in #5236 (f2723) - Remove deprecated
ssoClientexport from client plugin - by @Kinfe123 in #5307 (ee229) - GetAcccessToken refresh should properly refresh when oauth tokens are encrypted - by @bsklaroff in #5094 (16236)
- Resolve custom URL scheme origin matching with wildcards - by @AntonVishal and antonvishal in #5248 (82de6)
- Respect additionalFields returned config for user data when setting cookie cache - by @ahmed-abdat and @Bekacru in #5327 (a048f)
- Correct type
HookEndpointContextandInternalContext- by @himself65 in #5359 (89475) - Add optional chaining for process.platform - by @bytaesu in #5390 (f547d)
- User-agent requirement when fetching from clients - by @dvanmali in #5420 (5deb8)
- Unused peer dependency - by @himself65 in #5465 (3a343)
- Rename
shatobranchand made itcanaryby default - by @max-programming in #5491 (5bc26) - Remove deprecated forgetPassword endpoints - by @bytaesu in #5455 (7b62d)
- Respect onAPIError.errorURL in OAuth callb
Configuration
📅 Schedule: Branch creation - "" (UTC), 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.
SafeDep Report Summary
Package Details
| Package | Malware | Vulnerability | Risky License | Report |
|---|---|---|---|---|
@better-auth/core @ 1.4.5 pnpm-lock.yaml |
![]() |
![]() |
![]() |
🔗 |
@better-auth/telemetry @ 1.4.5 pnpm-lock.yaml |
![]() |
![]() |
![]() |
🔗 |
@better-auth/utils @ 0.3.0 pnpm-lock.yaml |
![]() |
![]() |
![]() |
🔗 |
@better-fetch/fetch @ 1.1.18 pnpm-lock.yaml |
![]() |
![]() |
![]() |
🔗 |
@noble/ciphers @ 2.1.1 pnpm-lock.yaml |
![]() |
![]() |
![]() |
🔗 |
@noble/hashes @ 2.0.1 pnpm-lock.yaml |
![]() |
![]() |
![]() |
🔗 |
@standard-schema/spec @ 1.1.0 pnpm-lock.yaml |
![]() |
![]() |
![]() |
🔗 |
better-auth @ 1.4.5 pnpm-lock.yaml |
![]() |
![]() |
![]() |
🔗 |
better-call @ 1.1.4 pnpm-lock.yaml |
![]() |
![]() |
![]() |
🔗 |
jose @ 6.1.3 pnpm-lock.yaml |
![]() |
![]() |
![]() |
🔗 |
kysely @ 0.28.9 pnpm-lock.yaml |
![]() |
![]() |
![]() |
🔗 |
ms @ 4.0.0-nightly.202508271359 pnpm-lock.yaml |
![]() |
![]() |
![]() |
🔗 |
nanostores @ 1.1.0 pnpm-lock.yaml |
![]() |
![]() |
![]() |
🔗 |
rou3 @ 0.7.12 pnpm-lock.yaml |
![]() |
![]() |
![]() |
🔗 |
set-cookie-parser @ 2.7.2 pnpm-lock.yaml |
![]() |
![]() |
![]() |
🔗 |
zod @ 4.2.1 pnpm-lock.yaml |
![]() |
![]() |
![]() |
🔗 |
This report is generated by SafeDep Github App
