@BETTER-AUTH/SSO · GHSA-mx9r-x6ww-qjw9 · Package
FIX → 1.7.3
In affected versions of the @better-auth/sso npm package, a signed-in user can register a personal SSO provider that copies a real provider's issuer and then match accounts linked through that real provider. Better Auth creates a session for the victim's account without victim interaction.
first public Sep 29, 2026 · 1 source
Could this affect your app?
Free first check from your website. Connect your repo for the full answer.
Applications that use the @better-auth/sso plugin with personal SSO provider registration enabled and without a resolveUser configuration. Exposure needs a Better Auth account, since the attacker must be able to register a provider. Applications on managed hosting, or that have not enabled SSO, are unlikely to be affected.
Not affected if resolveuser-configured, sso-not-used, version-1.7.3-or-later
Who cares better-auth, node, oidc, saml, sso, typescript
npm ls @better-auth/sso; affected versions are 1.7.0-rc.2 through 1.7.0-rc.6 and 1.7.0 through 1.7.2.resolveUser in the SSO plugin configuration; without it the exposed path is open.You may be affected if you use @better-auth/sso 1.7.0-rc.2 through 1.7.0-rc.6 or 1.7.0 through 1.7.2, and all of these conditions hold:
resolveUser.Configuring resolveUser requires an exact provider match and blocks this path. Setting providersLimit: 0 only stops new registrations; existing providers remain usable.
The SSO plugin lets signed-in users register an OIDC or SAML provider. In affected versions, sign-in through a personal provider could match an account linked through a different provider and create a session for that account.
Check it with your coding agent
It reads this page and tells you if your code is affected.
Are you affected?
Ask from here. InfraStack checks the affected versions against your stack and answers in your inbox.
InfraStack checks the affected versions against your stack and answers in Slack, with the evidence and the fix.
Upgrade to 1.7.3
@better-auth/sso 1.7.3providersLimit: 0 only stops new registrations and does not remove existing providers.An attacker with a Better Auth account can register a provider that copies a real provider's identity and reproduces a victim's user identifier. Better Auth then creates a new session for the victim's account without victim interaction.
The attack does not compromise the real identity provider or steal the victim's existing session.
Upgrade @better-auth/sso to 1.7.3 or later. The fix prevents one provider from matching an account linked through another provider.
If you cannot upgrade now, block SSO sign-in at your application boundary until you can install the fixed release.
Setting providersLimit: 0 prevents new personal-provider registration but does not disable providers that users already registered. If you keep SSO sign-in available, audit existing personal providers and remove any untrusted registrations. If you cannot verify that inventory, registration limits alone are only a partial mitigation.
If you already set resolveUser, the affected sign-in path requires an exact provider match. Upgrading is still the recommended fix.
Affected versions found linked accounts by the provider's issuer (the OIDC issuer or SAML entity ID) and the account identifier from the sign-in (the OIDC subject or SAML NameID). The lookup did not also check that the account belonged to the providerId that handled the sign-in.
An attacker could register a personal provider with the same OIDC issuer or SAML entity ID as a legitimate provider. The attacker still controlled the new provider's endpoints or signing keys, so it could assert the subject or NameID of an account linked through the legitimate provider. Because the lookup did not enforce the providerId boundary, Better Auth treated the victim's account as belonging to the attacker's provider and created a session for the victim. The assertion was valid for the attacker's provider, but it did not prove control of the legitimate provider's account namespace.
Version 1.7.3 restores account lookup using both the registered providerId and the asserted account identifier.