---
id: "GHSA-9hm7-xhfp-cx58"
page: "https://infrastack.ai/live/GHSA-9hm7-xhfp-cx58"
kind: "vulnerability"
aliases: ["GHSA-9hm7-xhfp-cx58"]
title: "better-auth: OAuth sign-in can treat an unverified provider email as verified"
severity: "medium"
cvss: 5.9
epss: null
exploited: false
status: "open"
category: "package"
products: [{"name": "better-auth", "fixed": ["1.7.16"], "affected": ">= 0.4.9, < 1.7.16", "ecosystem": "npm"}, {"name": "better-auth", "fixed": ["1.8.0-beta.5"], "affected": ">= 1.8.0-beta.0, < 1.8.0-beta.5", "ecosystem": "npm"}]
ecosystems: ["npm"]
tags: ["authentication", "better-auth", "cwe-1287", "cwe-287", "cwe-290", "node", "oauth", "package"]
not_affected_if: ["email-password-only", "trusted-providers-listed"]
published_at: "2026-11-03T21:39:17+00:00"
first_seen_at: "2026-11-09T22:53:20+00:00"
updated_at: "2026-11-09T22:56:12+00:00"
sources: [{"source": "ghsa-repo", "url": "https://github.com/better-auth/better-auth/security/advisories/GHSA-9hm7-xhfp-cx58", "first_seen_at": "2026-11-09T22:53:20+00:00"}]
exploit_sources: []
---

# better-auth: OAuth sign-in can treat an unverified provider email as verified

Link for people: https://infrastack.ai/live/GHSA-9hm7-xhfp-cx58 (this .md is for agents)

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.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- npm:better-auth affected >= 0.4.9, < 1.7.16 fixed 1.7.16
- npm:better-auth affected >= 1.8.0-beta.0, < 1.8.0-beta.5 fixed 1.8.0-beta.5

## How to check

- Check the installed version with `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.
- Check whether you use OAuth sign-in from a provider that sends `email_verified` as a string (Amazon Cognito user info is one example).
- Check whether you use `genericOAuth()` with a provider that has a JWKS endpoint.
- Check whether you use the Zoom provider with `disableSignUp`, `requireEmailVerification`, or `overrideUserInfoOnSignIn`.
- Check whether the affected providers are listed in `account.accountLinking.trustedProviders`; those are not affected.

## Fix

- `better-auth` `1.7.16` (stable line)
- `better-auth` `1.8.0-beta.5` (beta line)

## Timeline

- 2026-11-09T22:53:20+00:00 ghsa-repo https://github.com/better-auth/better-auth/security/advisories/GHSA-9hm7-xhfp-cx58

## Documents

- [advisory] Maintainer's advisory: github.com https://github.com/better-auth/better-auth/security/advisories/GHSA-9hm7-xhfp-cx58

## From the sources

## Am I affected?

You are affected if you use OAuth sign-in from `better-auth` 0.4.9 or later and **any** of these is true:

- A provider sends `email_verified` as a string and lets its users keep an unverified address. Amazon Cognito's user info endpoint is one example.
- You use `genericOAuth()` with a provider that has a JWKS endpoint.
- You use the Zoom provider with `disableSignUp`, `requireEmailVerification`, or `overrideUserInfoOnSignIn`.

You are not affected for providers listed in `account.accountLinking.trustedProviders`, where linking by email is intended.

## Summary

**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.

**Zoom options.** The Zoom provider ignored its configured provider options.

## Impact

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.

## Patches

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`.

## Workarounds

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.

## Technical details

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.

---

_Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai_
