Summary
@better-auth/sso provider registration has server-side request forgery via unvalidated OIDC endpoints
Full technical description
Am I affected?
Users are affected if all of the following are true:
- Their application uses
@better-auth/ssoat a version>= 0.1.0, < 1.6.11on the stable line, or any1.7.0-beta.xon the pre-release line. - The
sso()plugin is added to their application'sbetterAuth({ plugins: [...] })array. - Any user with a valid Better Auth session can reach
POST /sso/register(the plugin's default gate accepts any session).
For the non-blind SSRF impact (full IAM credential or internal HTTP body exfiltration), no further configuration is required.
For the account takeover escalation, additionally:
- Developers set
sso({ trustEmailVerified: true, ... }). - The developer's application deployment has accounts whose
emailoverlaps with attacker-chosen domains.
If developers do not enable the SSO plugin, their application is not affected.
Fix:
- Upgrade to
@better-auth/[email protected]or later. - If developers cannot upgrade, see workarounds below.
The @better-auth/sso plugin's POST /sso/register endpoint accepts attacker-controlled oidcConfig.userInfoEndpoint, tokenEndpoint, and jwksEndpoint URLs when skipDiscovery: true is set, persists them on the ssoProvider row without origin validation, then issues server-side fetches to those URLs during the OIDC callback. The fetched response body is reflected through the user profile, producing a non-blind SSRF reachable by any authenticated session. The same primitive exists on POST /sso/update-provider.
Details
The schema field types accept bare strings: no .url() validator, no origin gate. The discovery branch (skipDiscovery: false) routes URLs through validateDiscoveryUrl; the skip-discovery branch persists them as-is. At callback time three fetch sites read the stored URLs: validateAuthorizationCode for the token endpoint, betterFetch for the userInfo endpoint, and validateToken for the JWKS endpoint.
When trustEmailVerified: true is configured, the attacker can escalate to account linking. A malicious userInfo response with emailVerified: true and a chosen email triggers OAuth auto-link against any pre-existing user row with that email, compounding the SSRF into account takeover.
Workarounds
If developers cannot upgrade immediately:
- Disable provider self-registration: set
sso({ providersLimit: 0 }). The limit is enforced before the schema branch, blocking every/sso/registerregardless ofskipDiscovery. - Reverse-proxy gate: block
POST /sso/registerandPOST /sso/update-providerat the edge, or restrict to a denylist of source IPs and a small admin user list. - Network-level egress controls: block egress from the auth server to RFC 1918, RFC 4193, link-local ranges (
169.254.0.0/16,fe80::/10), and the cloud-metadata FQDN list at the firewall or VPC level. AWS users should additionally enforce IMDSv2 (HttpTokens: required). - Set
trustEmailVerified: falseuntil upgrade. This caps the impact at non-blind SSRF and removes the account-takeover escalation, but does not stop the SSRF.
Credit
Reported by Vaadata.
Resources
Impact
- Server-Side Request Forgery (non-blind): the attacker reads response bodies from any HTTP endpoint reachable from the auth server, including cloud metadata services (AWS IMDS, GCP metadata FQDN), internal-only APIs, and infrastructure services such as Redis or admin panels bound to localhost.
- Account takeover (when
trustEmailVerified: true): the attacker mints a malicious userInfo response assertingemailVerified: truefor an arbitrary email, triggering OAuth auto-link against pre-existing user rows.
The application does not adequately validate input before processing it, allowing unexpected values to reach sensitive code paths. Typical impact: varies by context: data corruption, logic bypass, or denial of service.
CVE-2026-53513 has a CVSS score of 9.6 (Critical). The vector is network-reachable, low privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (1.6.11); upgrading removes the vulnerable code path.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Already deployed Kodem?
See it in your environmentNew to Kodem? Get a demo →Remediation advice
Fixed in @better-auth/[email protected]. Provider registration (POST /sso/register with skipDiscovery: true) and every POST /sso/update-provider request now validate each supplied OIDC endpoint URL (authorizationEndpoint, tokenEndpoint, userInfoEndpoint, jwksEndpoint, discoveryEndpoint) at registration time. A URL is rejected unless it satisfies one of two conditions:
- Its host is publicly routable on the internet, evaluated through the
@better-auth/core/utils/host.isPublicRoutableHostgate. RFC 1918 private ranges, RFC 4193 unique-local addresses, link-local addresses (including the cloud-metadata IP169.254.169.254), loopback, multicast, broadcast, and reserved ranges are rejected, along with cloud-metadata FQDNs. - Its origin is already listed in the application's
trustedOriginsconfiguration. This preserves the documented escape hatch for customers running internal IdPs intentionally on private networks.
The schema also tightens from z.string() to z.url() on those fields, so malformed URLs fail at parse time rather than at fetch time. Deployments running internal IdPs that previously worked must add the IdP's origin to trustedOrigins to keep working after upgrade.
Frequently Asked Questions
- What is CVE-2026-53513? CVE-2026-53513 is a critical-severity improper input validation vulnerability in @better-auth/sso (npm), affecting versions >= 0.1.0, < 1.6.11. It is fixed in 1.6.11. The application does not adequately validate input before processing it, allowing unexpected values to reach sensitive code paths.
- How severe is CVE-2026-53513? CVE-2026-53513 has a CVSS score of 9.6 (Critical). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
- Which versions of @better-auth/sso are affected by CVE-2026-53513? @better-auth/sso (npm) versions >= 0.1.0, < 1.6.11 is affected.
- Is there a fix for CVE-2026-53513? Yes. CVE-2026-53513 is fixed in 1.6.11. Upgrade to this version or later.
- Is CVE-2026-53513 exploitable, and should I be worried? Whether CVE-2026-53513 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether CVE-2026-53513 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix CVE-2026-53513? Upgrade
@better-auth/ssoto 1.6.11 or later.