Every CVE Search/ Get API key

CVE-2026-67331

better-auth SCIM 1.5.0 before 1.7.0-beta.4 Authorization Bypass

8.7 HighFix available

better-auth SCIM versions from 1.5.0 before 1.7.0-beta.4 fail to bind non-organization SCIM providers to their creator by default, allowing authenticated users to manage other users' providers. Attackers can regenerate SCIM bearer tokens, invalidate legitimate tokens, and authenticate to SCIM API routes with the attacker-controlled token.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
Low

Exploit likelihood

0.39%Up 0.1 points since Aug 2, 2026
90%50%10%1%

What each source reports

CVE List Score used 8.7

better-auth SCIM 1.5.0 before 1.7.0-beta.4 Authorization Bypass

better-auth SCIM versions from 1.5.0 before 1.7.0-beta.4 fail to bind non-organization SCIM providers to their creator by default, allowing authenticated users to manage other users' providers. Attackers can regenerate SCIM bearer tokens, invalidate legitimate tokens, and authenticate to SCIM API routes with the attacker-controlled token.

Record
CVE-2026-67331
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:N/SI:N/SA:N
CVSS 3.1
8.3 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L
Weakness
CWE-639
Updated
2026-11-02
EUVDEUVD-2026-51846 8.7

better-auth SCIM versions from 1.5.0 before 1.7.0-beta.4 fail to bind non-organization SCIM providers to their creator by default, allowing authenticated users to manage other users' providers. Attackers can regenerate SCIM bearer tokens, invalidate legitimate tokens, and authenticate to SCIM API routes with the attacker-controlled token.

Record
EUVD-2026-51846
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:N/SI:N/SA:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-gj37-5j8h-j367 8.7

better-auth SCIM versions from 1.5.0 before 1.7.0-beta.4 fail to bind non-organization SCIM...

better-auth SCIM versions from 1.5.0 before 1.7.0-beta.4 fail to bind non-organization SCIM providers to their creator by default, allowing authenticated users to manage other users' providers. Attackers can regenerate SCIM bearer tokens, invalidate legitimate tokens, and authenticate to SCIM API routes with the attacker-controlled token.

Record
GHSA-gj37-5j8h-j367
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
CVSS 3.1
8.3 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L
Weakness
CWE-639
Updated
2026-11-02
GitHub AdvisoriesGHSA-j8v8-g9cx-5qf4 8.3

@better-auth/scim: Account/provider takeover via missing owner binding on non-org SCIM providers

Am I affected?

Users are affected if all of these hold:

  • They install and register the @better-auth/scim plugin (plugins: [scim()]).
  • They create SCIM providers without an organizationId, that is, non-organization ("personal") providers. Organization-scoped providers are not affected because they enforce organization membership and role.
  • Their application's deployment has more than one authenticated user, so one account can target another user's provider.
  • They have not set providerOwnership: { enabled: true }.

The SCIM management endpoints first shipped in 1.5.0, so every stable release from 1.5.0 onward is affected, and the stable line is not patched. On the pre-release line, builds through 1.7.0-beta.3 are affected, and 1.7.0-beta.4 carries the fix.

Fix:

  1. Upgrade to @better-auth/[email protected] (then 1.7.0). This is a breaking change: it removes the providerOwnership option, makes owner binding mandatory, and adds a permanent scimProvider.userId column.
  2. Run the schema migration after upgrading (npx auth migrate). Connections created before the upgrade carry no owner and become unreachable through the management endpoints, so reclaim them at the database level.
  3. The 1.6.x stable line is not patched. If developers stay on it, apply the workaround below.

Summary

@better-auth/scim does not bind non-organization SCIM providers to their creator in the default configuration. Any authenticated user can manage another user's non-org provider, including reading its metadata, listing connections, regenerating its SCIM bearer token, and deleting the connection. Regenerating the token rotates it: the legitimate token stops working and the attacker holds a valid one.

Details

The plugin tracks provider ownership through an opt-in providerOwnership option and a scimProvider.userId column. Both default to off. When ownership is disabled, a non-org provider row is created without a userId, and the management access check denies access only when a stored owner id is present and differs from the caller:

// non-organization branch of the access check
} else if (provider.userId && provider.userId !== userId) {
  throw new APIError("FORBIDDEN", { message: "You must be the owner to access this provider" });
}

Because the default row has no userId, the condition is false and the request is allowed. The same gap reaches every management operation: token generation and regeneration, single-provider read, the connection list (which returns providers where p.userId === userId || !p.userId), and provider deletion.

The most sensitive operation is token regeneration. If Alice creates a non-org provider corp-idp, Bob can call the same generate-token endpoint with providerId: "corp-idp". The existing row passes the ownerless access check, so the plugin deletes it, creates a fresh row, and returns a new SCIM bearer token to Bob. Alice's previous token is now invalid, and Bob's token authenticates against that provider's SCIM API routes.

This requires no organization membership and no elevated role. It is reachable in the default scim() configuration whenever non-organization providers are used.

Proof of concept

Two authenticated users, Alice and Bob, in a default scim() setup:

  1. Alice signs in and creates a non-org provider: POST /scim/generate-token with { "providerId": "corp-idp" }.
  2. Bob signs in and reads Alice's provider: GET /scim/get-provider-connection?providerId=corp-idp returns 200 with { "providerId": "corp-idp" }.
  3. Bob regenerates the token: POST /scim/generate-token with { "providerId": "corp-idp" } returns 201 and a new scimToken.
  4. Alice's old token is rejected at GET /scim/v2/Users (401); Bob's regenerated token is accepted (200).

The behavior is reproducible through Better Auth's public API surface with two distinct sessions.

Patches

Fixed in @better-auth/[email protected] (then 1.7.0). The fix…

Record
GHSA-j8v8-g9cx-5qf4
CVSS 3.1
8.3 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L
Weakness
CWE-639, CWE-862
Updated
2026-11-02
NVD 8.7

better-auth SCIM versions from 1.5.0 before 1.7.0-beta.4 fail to bind non-organization SCIM providers to their creator by default, allowing authenticated users to manage other users' providers. Attackers can regenerate SCIM bearer tokens, invalidate legitimate tokens, and authenticate to SCIM API routes with the attacker-controlled token.

Record
CVE-2026-67331
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
CVSS 3.1
8.3 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L
Weakness
CWE-639
Updated
2026-11-02
OSV 8.7

better-auth SCIM 1.5.0 before 1.7.0-beta.4 Authorization Bypass

better-auth SCIM versions from 1.5.0 before 1.7.0-beta.4 fail to bind non-organization SCIM providers to their creator by default, allowing authenticated users to manage other users' providers. Attackers can regenerate SCIM bearer tokens, invalidate legitimate tokens, and authenticate to SCIM API routes with the attacker-controlled token.

Record
CVE-2026-67331
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:N/SI:N/SA:N
Weakness
CWE-639
Updated
2026-11-02
OSVGHSA-j8v8-g9cx-5qf4 8.3

@better-auth/scim: Account/provider takeover via missing owner binding on non-org SCIM providers

Am I affected?

Users are affected if all of these hold:

  • They install and register the @better-auth/scim plugin (plugins: [scim()]).
  • They create SCIM providers without an organizationId, that is, non-organization ("personal") providers. Organization-scoped providers are not affected because they enforce organization membership and role.
  • Their application's deployment has more than one authenticated user, so one account can target another user's provider.
  • They have not set providerOwnership: { enabled: true }.

The SCIM management endpoints first shipped in 1.5.0, so every stable release from 1.5.0 onward is affected, and the stable line is not patched. On the pre-release line, builds through 1.7.0-beta.3 are affected, and 1.7.0-beta.4 carries the fix.

Fix:

  1. Upgrade to @better-auth/[email protected] (then 1.7.0). This is a breaking change: it removes the providerOwnership option, makes owner binding mandatory, and adds a permanent scimProvider.userId column.
  2. Run the schema migration after upgrading (npx auth migrate). Connections created before the upgrade carry no owner and become unreachable through the management endpoints, so reclaim them at the database level.
  3. The 1.6.x stable line is not patched. If developers stay on it, apply the workaround below.

Summary

@better-auth/scim does not bind non-organization SCIM providers to their creator in the default configuration. Any authenticated user can manage another user's non-org provider, including reading its metadata, listing connections, regenerating its SCIM bearer token, and deleting the connection. Regenerating the token rotates it: the legitimate token stops working and the attacker holds a valid one.

Details

The plugin tracks provider ownership through an opt-in providerOwnership option and a scimProvider.userId column. Both default to off. When ownership is disabled, a non-org provider row is created without a userId, and the management access check denies access only when a stored owner id is present and differs from the caller:

// non-organization branch of the access check
} else if (provider.userId && provider.userId !== userId) {
  throw new APIError("FORBIDDEN", { message: "You must be the owner to access this provider" });
}

Because the default row has no userId, the condition is false and the request is allowed. The same gap reaches every management operation: token generation and regeneration, single-provider read, the connection list (which returns providers where p.userId === userId || !p.userId), and provider deletion.

The most sensitive operation is token regeneration. If Alice creates a non-org provider corp-idp, Bob can call the same generate-token endpoint with providerId: "corp-idp". The existing row passes the ownerless access check, so the plugin deletes it, creates a fresh row, and returns a new SCIM bearer token to Bob. Alice's previous token is now invalid, and Bob's token authenticates against that provider's SCIM API routes.

This requires no organization membership and no elevated role. It is reachable in the default scim() configuration whenever non-organization providers are used.

Proof of concept

Two authenticated users, Alice and Bob, in a default scim() setup:

  1. Alice signs in and creates a non-org provider: POST /scim/generate-token with { "providerId": "corp-idp" }.
  2. Bob signs in and reads Alice's provider: GET /scim/get-provider-connection?providerId=corp-idp returns 200 with { "providerId": "corp-idp" }.
  3. Bob regenerates the token: POST /scim/generate-token with { "providerId": "corp-idp" } returns 201 and a new scimToken.
  4. Alice's old token is rejected at GET /scim/v2/Users (401); Bob's regenerated token is accepted (200).

The behavior is reproducible through Better Auth's public API surface with two distinct sessions.

Patches

Fixed in @better-auth/[email protected] (then 1.7.0). The fix…

Record
GHSA-j8v8-g9cx-5qf4
CVSS 3.1
8.3 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L
Weakness
CWE-639, CWE-862
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
@better-auth/scim
npm
1.5.0 up to 1.7.0-beta.4
1.7.0-beta.4

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-67331 is a high vulnerability (CVSS 8.7) in Better-auth Scim, published July 7, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.39%, the 33rd percentile. Fixed in @better-auth/scim 1.7.0-beta.4.

References

This page doesn't list everything

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

MoveEnter Open