BETTER-AUTH · GHSA-9hm7-xhfp-cx58 · Package
FIX → 1.8.0-beta.5 +1
better-auth treated any non-empty email_verified claim as verified, so the string "false" passed, and some OAuth providers and Zoom options were not enforced. An attacker who controls an unverified address at an affected provider can sign in and be linked to the local account that owns that address.
first public Nov 3, 2026 · 1 source
Could this affect your app?
Free first check from your website. Connect your repo for the full answer.
Applications that use better-auth for OAuth sign-in and link provider logins to existing local accounts by email. Exposure depends on whether the identity provider sends string email_verified values, whether genericOAuth() is used with a JWKS provider, or whether the Zoom provider is used with the affected options. Apps that only use email and password, or that list the relevant providers in trustedProviders, are not affected.
Not affected if email-password-only, trusted-providers-listed
Who cares authentication, better-auth, node, oauth
npm ls better-auth; affected if below 1.7.16 on the stable line, or between 1.8.0-beta.0 and 1.8.0-beta.4 on the beta line.email_verified as a string (Amazon Cognito user info is one example).You are affected if you use OAuth sign-in from better-auth 0.4.9 or later and any of these is true:
email_verified as a string and lets its users keep an unverified address. Amazon Cognito's user info endpoint is one example.genericOAuth() with a provider that has a JWKS endpoint.disableSignUp, requireEmailVerification, or overrideUserInfoOnSignIn.You are not affected for providers listed in account.accountLinking.trustedProviders, where linking by email is intended.
String claims. Better Auth treated any non-empty email_verified value as verified, so the string "false" passed.
Profile and token mismatch. With generic OAuth, the user info profile was not checked against the ID token's subject, and direct ID-token sign-in could load the profile from a submitted access token.
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.
genericOAuth() with a provider that has a JWKS endpoint.disableSignUp, requireEmailVerification, or overrideUserInfoOnSignIn.account.accountLinking.trustedProviders; those are not affected.Upgrade to 1.8.0-beta.5 +1
better-auth 1.7.16 (stable line)better-auth 1.8.0-beta.5 (beta line)Zoom options. The Zoom provider ignored its configured provider options.
Someone who can hold another person's address unverified at an affected provider can sign in and be linked to the local account that owns it, and gets a session for that account. Accounts created this way are marked verified. A profile mismatch can attach a different provider identity than the one the ID token names. On Zoom, closed registration and email verification requirements did not apply.
Upgrade better-auth to 1.7.16, or to 1.8.0-beta.5 on the beta line.
An email now counts as verified only when the claim is true or the string "true", including values returned from mapProfileToUser.
For a provider that sends string claims, provide a getUserInfo function that converts email_verified to a boolean. For Zoom, turn off the provider if you rely on the ignored options.
The linking code tested emailVerified for truthiness when deciding whether an untrusted provider may link to an existing user and when storing the value for a new user. It now normalizes the claim at those points. Generic OAuth providers with a jwks_uri now reject a profile whose sub differs from the ID token, and ID-token sign-in ignores submitted access and refresh tokens. Direct ID-token sign-in already applied disableSignUp from 1.7.7. This release applies the Zoom provider's options the same way.