[PR #6051] [CLOSED] Fix/security org member leak #14656

Closed
opened 2026-04-13 09:34:04 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/6051
Author: @sivaratrisrinivas
Created: 11/17/2025
Status: Closed

Base: canaryHead: fix/security-org-member-leak


📝 Commits (3)

  • 04712dc fix(haveibeenpwned): prevent email enumeration via compromised password check
  • d19b1b2 chore: apply biome formatting
  • 9027a8a Restrict full organization roster access

📊 Changes

12 files changed (+203 additions, -10 deletions)

View changed files

📝 docs/content/docs/plugins/organization.mdx (+15 -0)
📝 packages/better-auth/src/api/routes/sign-in.ts (+3 -1)
📝 packages/better-auth/src/crypto/password.ts (+4 -1)
📝 packages/better-auth/src/plugins/haveibeenpwned/haveibeenpwned.test.ts (+11 -0)
📝 packages/better-auth/src/plugins/haveibeenpwned/index.ts (+10 -3)
📝 packages/better-auth/src/plugins/organization/error-codes.ts (+2 -0)
📝 packages/better-auth/src/plugins/organization/routes/crud-org.test.ts (+119 -0)
📝 packages/better-auth/src/plugins/organization/routes/crud-org.ts (+15 -2)
📝 packages/better-auth/src/plugins/organization/types.ts (+6 -0)
📝 packages/core/src/types/context.ts (+8 -1)
📝 packages/core/src/types/index.ts (+1 -0)
📝 packages/core/src/types/init-options.ts (+9 -2)

📄 Description

What

Restricts /organization/get-full-organization to owner and admin by default. Adds fullOrganizationAccessRoles to allow other roles.

Why

Previously, any member could call the endpoint and see all members (emails, names, metadata). In multi-tenant SaaS where members are end-customers, this exposes private data. Fixes #6038.

How

  • Added role check in getFullOrganization endpoint
  • Default allowed roles: ["owner", "admin"]
  • Configurable via fullOrganizationAccessRoles option
  • Returns FORBIDDEN with YOU_ARE_NOT_ALLOWED_TO_READ_THIS_ORGANIZATION for unauthorized roles
  • Added tests for default deny and configurable override
  • Updated docs with security note and config example

Changes

  • crud-org.ts: Added role validation before returning org data
  • types.ts: Added fullOrganizationAccessRoles option
  • error-codes.ts: Added new error code
  • crud-org.test.ts: Added tests for default deny and override
  • organization.mdx: Documented security restriction and config

Breaking Change

Yes. Members can no longer access the full roster by default. Apps that need broader access can set fullOrganizationAccessRoles: ["owner", "admin", "member"].

Testing

All organization route tests pass.


Summary by cubic

Tightened organization roster permissions and hardened sign-in to prevent data leaks. The full org endpoint now defaults to owner/admin access, and HaveIBeenPwned no longer leaks valid emails via error messages.

  • Bug Fixes

    • Restricted /organization/get-full-organization to owner and admin by default; new fullOrganizationAccessRoles option allows broader access.
    • Added a 403 error for unauthorized roles with a clear error code; updated docs and tests.
    • Introduced PasswordHashOptions.skipCompromiseCheck and used it during dummy hashing for unknown emails.
    • Updated HaveIBeenPwned plugin to honor skipCompromiseCheck, ensuring unknown users get a generic 401 “Invalid email or password”; added tests.
  • Migration

    • Breaking change: members can no longer read the full roster by default. If needed, configure fullOrganizationAccessRoles to include "member".

Written for commit 9027a8af55. Summary will update automatically on new commits.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/6051 **Author:** [@sivaratrisrinivas](https://github.com/sivaratrisrinivas) **Created:** 11/17/2025 **Status:** ❌ Closed **Base:** `canary` ← **Head:** `fix/security-org-member-leak` --- ### 📝 Commits (3) - [`04712dc`](https://github.com/better-auth/better-auth/commit/04712dc0c7d8b9384057783ea49969aa46766a9b) fix(haveibeenpwned): prevent email enumeration via compromised password check - [`d19b1b2`](https://github.com/better-auth/better-auth/commit/d19b1b2e55916bcd050a6e27cc31424939560019) chore: apply biome formatting - [`9027a8a`](https://github.com/better-auth/better-auth/commit/9027a8af5589768f7c7d40a41ea3438caa720bb3) Restrict full organization roster access ### 📊 Changes **12 files changed** (+203 additions, -10 deletions) <details> <summary>View changed files</summary> 📝 `docs/content/docs/plugins/organization.mdx` (+15 -0) 📝 `packages/better-auth/src/api/routes/sign-in.ts` (+3 -1) 📝 `packages/better-auth/src/crypto/password.ts` (+4 -1) 📝 `packages/better-auth/src/plugins/haveibeenpwned/haveibeenpwned.test.ts` (+11 -0) 📝 `packages/better-auth/src/plugins/haveibeenpwned/index.ts` (+10 -3) 📝 `packages/better-auth/src/plugins/organization/error-codes.ts` (+2 -0) 📝 `packages/better-auth/src/plugins/organization/routes/crud-org.test.ts` (+119 -0) 📝 `packages/better-auth/src/plugins/organization/routes/crud-org.ts` (+15 -2) 📝 `packages/better-auth/src/plugins/organization/types.ts` (+6 -0) 📝 `packages/core/src/types/context.ts` (+8 -1) 📝 `packages/core/src/types/index.ts` (+1 -0) 📝 `packages/core/src/types/init-options.ts` (+9 -2) </details> ### 📄 Description ## What Restricts `/organization/get-full-organization` to `owner` and `admin` by default. Adds `fullOrganizationAccessRoles` to allow other roles. ## Why Previously, any member could call the endpoint and see all members (emails, names, metadata). In multi-tenant SaaS where members are end-customers, this exposes private data. Fixes #6038. ## How - Added role check in `getFullOrganization` endpoint - Default allowed roles: `["owner", "admin"]` - Configurable via `fullOrganizationAccessRoles` option - Returns `FORBIDDEN` with `YOU_ARE_NOT_ALLOWED_TO_READ_THIS_ORGANIZATION` for unauthorized roles - Added tests for default deny and configurable override - Updated docs with security note and config example ## Changes - `crud-org.ts`: Added role validation before returning org data - `types.ts`: Added `fullOrganizationAccessRoles` option - `error-codes.ts`: Added new error code - `crud-org.test.ts`: Added tests for default deny and override - `organization.mdx`: Documented security restriction and config ## Breaking Change Yes. Members can no longer access the full roster by default. Apps that need broader access can set `fullOrganizationAccessRoles: ["owner", "admin", "member"]`. ## Testing All organization route tests pass. <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Tightened organization roster permissions and hardened sign-in to prevent data leaks. The full org endpoint now defaults to owner/admin access, and HaveIBeenPwned no longer leaks valid emails via error messages. - **Bug Fixes** - Restricted /organization/get-full-organization to owner and admin by default; new fullOrganizationAccessRoles option allows broader access. - Added a 403 error for unauthorized roles with a clear error code; updated docs and tests. - Introduced PasswordHashOptions.skipCompromiseCheck and used it during dummy hashing for unknown emails. - Updated HaveIBeenPwned plugin to honor skipCompromiseCheck, ensuring unknown users get a generic 401 “Invalid email or password”; added tests. - **Migration** - Breaking change: members can no longer read the full roster by default. If needed, configure fullOrganizationAccessRoles to include "member". <sup>Written for commit 9027a8af5589768f7c7d40a41ea3438caa720bb3. Summary will update automatically on new commits.</sup> <!-- End of auto-generated description by cubic. --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-13 09:34:04 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#14656