Beter Auth has an Open Redirect via Scheme-Less Callback Parameter
Description
Better Auth before v1.1.21 allows open redirect via scheme-less URLs in callbackURL parameters, bypassing a previous fix.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Better Auth before v1.1.21 allows open redirect via scheme-less URLs in callbackURL parameters, bypassing a previous fix.
Vulnerability
Overview
Better Auth, a TypeScript authentication library, contains an open redirect vulnerability in endpoints that accept a callbackURL parameter, including the email verification endpoint. Prior to version 1.1.21, the server validated callback URLs by blocking fully qualified URLs (e.g., https://evil.com), but incorrectly allowed scheme-less URLs like //evil.com or %5C/evil.com. The browser interprets such strings as fully qualified URLs, leading to unintended redirection after a successful action like email verification [1][3].
Exploitation
Method
An attacker can exploit this flaw by crafting a malicious verification link containing a scheme-less callback URL and tricking a user into clicking it. The user's browser interprets the callback as a valid external URL, and upon completing the verification process, the victim is automatically redirected to an attacker-controlled site. No authentication is required to trigger the redirect; the vulnerability exists in the URL validation logic for GET-based redirect endpoints [1][2].
Impact
Successful exploitation enables phishing attacks, malware distribution, or theft of sensitive authentication tokens by redirecting users to a malicious domain that mimics a legitimate service. This can erode user trust and compromise account security. The advisory notes that CVE-2025-27143 is a bypass of the previous fix for GHSA-8jhw-6pjj-8723/CVE-2024-56734, meaning the original patch did not fully address the issue [1][4].
Mitigation
The vulnerability is patched in Better Auth version 1.1.21, released on 2025-02-24. The fix introduces a stricter regex validation pattern (/^/(?![\/%])[\w\-./]*$/) to reject scheme-less and path-traversal patterns like backslash-encoded strings or double slashes [2][3]. All users are advised to upgrade immediately. No workaround has been provided for this specific bypass.
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
better-authnpm | < 1.1.20 | 1.1.20 |
Affected products
2- Range: < 1.1.20
Patches
2b381cac7aafdfix(origin-check): add tests for callback URLs with malicious patterns
2 files changed · +32 −4
packages/better-auth/src/api/middlewares/origin-check.test.ts+30 −0 modified@@ -206,6 +206,36 @@ describe("Origin Check", async (it) => { expect(res.error?.status).toBe(403); }); + it("shouldn't work with callback url with malicious", async (ctx) => { + const client = createAuthClient({ + baseURL: "http://localhost:3000", + fetchOptions: { + customFetchImpl, + headers: { + origin: "https://localhost:3000", + }, + }, + }); + const res = await client.signIn.email({ + email: testUser.email, + password: testUser.password, + callbackURL: "/%5C/evil.com", + }); + expect(res.error?.status).toBe(403); + const res2 = await client.signIn.email({ + email: testUser.email, + password: testUser.password, + callbackURL: `/\/\/evil.com`, + }); + expect(res2.error?.status).toBe(403); + const res3 = await client.signIn.email({ + email: testUser.email, + password: testUser.password, + callbackURL: "/%5C/evil.com", + }); + expect(res3.error?.status).toBe(403); + }); + it("should work with GET requests", async (ctx) => { const client = createAuthClient({ baseURL: "https://sub-domain.my-site.com",
packages/better-auth/src/api/middlewares/origin-check.ts+2 −4 modified@@ -49,8 +49,7 @@ export const originCheckMiddleware = createAuthMiddleware(async (ctx) => { matchesPattern(url, origin) || (url?.startsWith("/") && label !== "origin" && - !url.includes(":") && - !url.includes("//")), + /^\/(?![\\/%])[\w\-./]*$/.test(url)), ); if (!isTrustedOrigin) { ctx.context.logger.error(`Invalid ${label}: ${url}`); @@ -107,8 +106,7 @@ export const originCheck = ( matchesPattern(url, origin) || (url?.startsWith("/") && label !== "origin" && - !url.includes(":") && - !url.includes("//")), + /^\/(?![\\/%])[\w\-./]*$/.test(url)), ); if (!isTrustedOrigin) { ctx.context.logger.error(`Invalid ${label}: ${url}`);
24659aefc35afix(origin-check): prevent URLs with double slashes from being trusted
1 file changed · +4 −1
packages/better-auth/src/api/middlewares/origin-check.ts+4 −1 modified@@ -47,7 +47,10 @@ export const originCheckMiddleware = createAuthMiddleware(async (ctx) => { const isTrustedOrigin = trustedOrigins.some( (origin) => matchesPattern(url, origin) || - (url?.startsWith("/") && label !== "origin" && !url.includes(":")), + (url?.startsWith("/") && + label !== "origin" && + !url.includes(":") && + !url.includes("//")), ); if (!isTrustedOrigin) { ctx.context.logger.error(`Invalid ${label}: ${url}`);
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-hjpm-7mrm-26w8ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-27143ghsaADVISORY
- github.com/better-auth/better-auth/commit/24659aefc35a536b95ea4e5347e52c8803910153ghsax_refsource_MISCWEB
- github.com/better-auth/better-auth/commit/b381cac7aafd6aa53ef78b6ab771ebfa24643c80ghsax_refsource_MISCWEB
- github.com/better-auth/better-auth/releases/tag/v1.1.21ghsax_refsource_MISCWEB
- github.com/better-auth/better-auth/security/advisories/GHSA-8jhw-6pjj-8723ghsax_refsource_MISCWEB
- github.com/better-auth/better-auth/security/advisories/GHSA-hjpm-7mrm-26w8ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.