Every CVE Search/ Get API key

CVE-2026-53514

Better Auth: Unauthorized invitation acceptance via unverified email match in organization plugin

7.7 HighFix available

Better Auth is an authentication and authorization library for TypeScript. Prior to 1.6.11, and in 1.6.14 and later when invitation IDs can be obtained outside the invited mailbox and requireEmailVerificationOnInvitation: true is not enabled, the organization plugin's acceptInvitation, rejectInvitation, getInvitation, and listUserInvitations recipient endpoints use session.user.email and an invitation ID without sufficient verified-email ownership proof, allowing a user with an unverified session for the invited email address to accept an organization invitation after obtaining the invitation ID. This issue is fixed for the original default behavior in version 1.6.11, while 1.6.14 restored compatibility for built-in opaque invitation IDs and leaves affected configurations requiring secure options.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
High
Privileges needed
Low
User interaction
Required

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
None

Exploit likelihood

0.20%Up 0.2 points since Jun 12, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.7

Better Auth: Unauthorized invitation acceptance via unverified email match in organization plugin

Better Auth is an authentication and authorization library for TypeScript. Prior to 1.6.11, and in 1.6.14 and later when invitation IDs can be obtained outside the invited mailbox and requireEmailVerificationOnInvitation: true is not enabled, the organization plugin's acceptInvitation, rejectInvitation, getInvitation, and listUserInvitations recipient endpoints use session.user.email and an invitation ID without sufficient verified-email ownership proof, allowing a user with an unverified session for the invited email address to accept an organization invitation after obtaining the invitation ID. This issue is fixed for the original default behavior in version 1.6.11, while 1.6.14 restored compatibility for built-in opaque invitation IDs and leaves affected configurations requiring secure options.

Record
CVE-2026-53514
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:N
Weakness
CWE-287, CWE-345, CWE-441, CWE-862
Updated
2026-11-02
EUVDEUVD-2026-44742 7.7

Better Auth is an authentication and authorization library for TypeScript. Prior to 1.6.11, and in 1.6.14 and later when invitation IDs can be obtained outside the invited mailbox and requireEmailVerificationOnInvitation: true is not enabled, the organization plugin's acceptInvitation, rejectInvitation, getInvitation, and listUserInvitations recipient endpoints use session.user.email and an invitation ID without sufficient verified-email ownership proof, allowing a user with an unverified session for the invited email address to accept an organization invitation after obtaining the invitation ID. This issue is fixed for the original default behavior in version 1.6.11, while 1.6.14 restored compatibility for built-in opaque invitation IDs and leaves affected configurations requiring secure options.

Record
EUVD-2026-44742
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-fmh4-wcc4-5jm3 7.7

Better Auth vulnerable to unauthorized invitation acceptance via unverified email match in organization plugin

Am I affected?

Users are affected if all of the following are true:

  • Their application uses better-auth with the organization plugin (import { organization } from "better-auth/plugins/organization").
  • Their application enables a sign-up surface that allows arbitrary unverified email registration. Most commonly emailAndPassword: { enabled: true } without requireEmailVerification: true.
  • Their application has not set requireEmailVerificationOnInvitation: true on the organization() options.
  • Their application invitation distribution flow allows anyone other than the invited mailbox owner to obtain the invitationId. Examples: admin UI surfacing the link, copy-paste into chat, forwarded email, mail-forwarding rules at the recipient's domain, link previews logging the URL, or a custom sendInvitationEmail integration that sends to a non-owner channel.

If their application set emailAndPassword: { enabled: true, requireEmailVerification: true } so unverified rows cannot reach a usable session, they are not affected. Setting requireEmailVerificationOnInvitation: true closes acceptInvitation and rejectInvitation, but getInvitation and listUserInvitations remain ungated even with that flag.

Fix:

  1. Upgrade to [email protected] or later.
  2. If developers cannot upgrade their application, see workarounds below.

Summary

The organization plugin's acceptInvitation endpoint trusts an email-string equality check as proof that the session user owns the invited address. With Better Auth's stock emailAndPassword: { enabled: true } configuration, requireEmailVerification defaults to false, so an attacker can sign up a row keyed to [email protected] (auto-signed-in, emailVerified: false) before the legitimate owner. When an organization admin invites that address, the attacker presents the invitationId and accepts the invitation, joining the organization at the invited role.

Details

The recipient gate compares invitation.email.toLowerCase() to session.user.email.toLowerCase() and returns 403 on mismatch. The opt-in requireEmailVerificationOnInvitation flag adds an emailVerified check, but it defaults to false and only fires on acceptInvitation and rejectInvitation; getInvitation and listUserInvitations have no emailVerified gate at all.

The bearer token (invitationId) is by default 32 chars over [a-zA-Z0-9] (~190 bits), so the realistic attack vector is leakage of the invitation link rather than brute force.

The fix shape defaults the emailVerified gate to on and extends it across all four invitation endpoints (acceptInvitation, rejectInvitation, getInvitation, listUserInvitations). This is the same trust-primitive class as GHSA-g38m-r43w-p2q7 (OAuth auto-link); both ship the rule "email equality is not ownership proof; both sides must prove ownership".

Patches

Fixed in [email protected]. All four invitation recipient endpoints (acceptInvitation, rejectInvitation, getInvitation, listUserInvitations) now require the session user's emailVerified to be true in addition to the email-string match. The requireEmailVerificationOnInvitation option default flips from false to true, so applications are secure out of the box.

getInvitation and listUserInvitations use the new EMAIL_VERIFICATION_REQUIRED_FOR_INVITATION error code so the wording matches the operation; acceptInvitation and rejectInvitation keep the existing EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION code. Server-side calls to listUserInvitations that pass ctx.query.email without an authenticated session continue to bypass the gate; the gate is specific to session-authenticated recipient calls.

Integrators who intentionally accept invitations on unverified sessions can preserve the legacy permissive behavior with organization({ requireEmailVerificationOnInvitation: false }). The option is marked @deprecated; the…

Record
GHSA-fmh4-wcc4-5jm3
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:N
Weakness
CWE-287, CWE-345, CWE-441, CWE-862
Updated
2026-11-02
NVD 7.7

Better Auth is an authentication and authorization library for TypeScript. Prior to 1.6.11, and in 1.6.14 and later when invitation IDs can be obtained outside the invited mailbox and requireEmailVerificationOnInvitation: true is not enabled, the organization plugin's acceptInvitation, rejectInvitation, getInvitation, and listUserInvitations recipient endpoints use session.user.email and an invitation ID without sufficient verified-email ownership proof, allowing a user with an unverified session for the invited email address to accept an organization invitation after obtaining the invitation ID. This issue is fixed for the original default behavior in version 1.6.11, while 1.6.14 restored compatibility for built-in opaque invitation IDs and leaves affected configurations requiring secure options.

Record
CVE-2026-53514
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:N
Weakness
CWE-287, CWE-345, CWE-441, CWE-862
Updated
2026-11-02
OSV 7.7

Better Auth: Unauthorized invitation acceptance via unverified email match in organization plugin

Better Auth is an authentication and authorization library for TypeScript. Prior to 1.6.11, and in 1.6.14 and later when invitation IDs can be obtained outside the invited mailbox and requireEmailVerificationOnInvitation: true is not enabled, the organization plugin's acceptInvitation, rejectInvitation, getInvitation, and listUserInvitations recipient endpoints use session.user.email and an invitation ID without sufficient verified-email ownership proof, allowing a user with an unverified session for the invited email address to accept an organization invitation after obtaining the invitation ID. This issue is fixed for the original default behavior in version 1.6.11, while 1.6.14 restored compatibility for built-in opaque invitation IDs and leaves affected configurations requiring secure options.

Record
CVE-2026-53514
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:N
Weakness
CWE-287, CWE-345, CWE-441, CWE-862
Updated
2026-11-02
OSVGHSA-fmh4-wcc4-5jm3 7.7

Better Auth vulnerable to unauthorized invitation acceptance via unverified email match in organization plugin

Am I affected?

Users are affected if all of the following are true:

  • Their application uses better-auth with the organization plugin (import { organization } from "better-auth/plugins/organization").
  • Their application enables a sign-up surface that allows arbitrary unverified email registration. Most commonly emailAndPassword: { enabled: true } without requireEmailVerification: true.
  • Their application has not set requireEmailVerificationOnInvitation: true on the organization() options.
  • Their application invitation distribution flow allows anyone other than the invited mailbox owner to obtain the invitationId. Examples: admin UI surfacing the link, copy-paste into chat, forwarded email, mail-forwarding rules at the recipient's domain, link previews logging the URL, or a custom sendInvitationEmail integration that sends to a non-owner channel.

If their application set emailAndPassword: { enabled: true, requireEmailVerification: true } so unverified rows cannot reach a usable session, they are not affected. Setting requireEmailVerificationOnInvitation: true closes acceptInvitation and rejectInvitation, but getInvitation and listUserInvitations remain ungated even with that flag.

Fix:

  1. Upgrade to [email protected] or later.
  2. If developers cannot upgrade their application, see workarounds below.

Summary

The organization plugin's acceptInvitation endpoint trusts an email-string equality check as proof that the session user owns the invited address. With Better Auth's stock emailAndPassword: { enabled: true } configuration, requireEmailVerification defaults to false, so an attacker can sign up a row keyed to [email protected] (auto-signed-in, emailVerified: false) before the legitimate owner. When an organization admin invites that address, the attacker presents the invitationId and accepts the invitation, joining the organization at the invited role.

Details

The recipient gate compares invitation.email.toLowerCase() to session.user.email.toLowerCase() and returns 403 on mismatch. The opt-in requireEmailVerificationOnInvitation flag adds an emailVerified check, but it defaults to false and only fires on acceptInvitation and rejectInvitation; getInvitation and listUserInvitations have no emailVerified gate at all.

The bearer token (invitationId) is by default 32 chars over [a-zA-Z0-9] (~190 bits), so the realistic attack vector is leakage of the invitation link rather than brute force.

The fix shape defaults the emailVerified gate to on and extends it across all four invitation endpoints (acceptInvitation, rejectInvitation, getInvitation, listUserInvitations). This is the same trust-primitive class as GHSA-g38m-r43w-p2q7 (OAuth auto-link); both ship the rule "email equality is not ownership proof; both sides must prove ownership".

Patches

Fixed in [email protected]. All four invitation recipient endpoints (acceptInvitation, rejectInvitation, getInvitation, listUserInvitations) now require the session user's emailVerified to be true in addition to the email-string match. The requireEmailVerificationOnInvitation option default flips from false to true, so applications are secure out of the box.

getInvitation and listUserInvitations use the new EMAIL_VERIFICATION_REQUIRED_FOR_INVITATION error code so the wording matches the operation; acceptInvitation and rejectInvitation keep the existing EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION code. Server-side calls to listUserInvitations that pass ctx.query.email without an authenticated session continue to bypass the gate; the gate is specific to session-authenticated recipient calls.

Integrators who intentionally accept invitations on unverified sessions can preserve the legacy permissive behavior with organization({ requireEmailVerificationOnInvitation: false }). The option is marked @deprecated; the…

Record
GHSA-fmh4-wcc4-5jm3
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:N
Weakness
CWE-287, CWE-345, CWE-441, CWE-862
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
better-auth
npm
before 1.6.11
1.6.11

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-53514 is a high vulnerability (CVSS 7.7) in Better-auth Better Auth, published July 7, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.20%, the 10th percentile. Fixed in better-auth 1.6.11.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open