Skip to content

security: bind invite acceptance to the invited identity and stop roster token disclosure #592

Description

@seonghobae

Protected-shipped defect

Fresh protected develop@2c328875e00e86537df3e965170be80532571cad currently exposes pending invite bearer tokens through GET /api/orgs/:id/members to any organization member (including viewer) and accepts POST /api/invites/:token/accept for any authenticated account that possesses the token, without checking that the authenticated user's email matches the invited email.

This was independently surfaced by current-head review on #589 and verified directly against protected source. It is not a Stripe-specific defect and should not be hidden by closing that review as out-of-scope.

Security consequence

A low-privilege member can read a pending invite token from the roster response, then another authenticated account can redeem it and inherit the invite's role, including admin. Token possession is therefore sufficient for cross-identity privilege acquisition.

RED acceptance

Add realistic API regressions that prove all of the following before changing production behavior:

  1. a viewer/ordinary member roster response never contains invite token values;
  2. an authenticated account whose normalized email does not match the pending invite receives the existing stable invalid-invite response and gains no membership;
  3. the intended invited account can still accept exactly once and receives the invited role;
  4. used/missing tokens retain current fail-closed behavior;
  5. email comparison uses the same canonical case-insensitive identity semantics as signup/login so the repair does not strand legitimate historical mixed-case identities.

Smallest causal repair

  • Remove token from the pending-invite projection returned by the members endpoint.
  • In the acceptance transaction/path, load the authenticated user's canonical email and require it to match the invite email before member-limit checks, membership insertion, audit, delivery, or marking the invite accepted.
  • Preserve existing tenant/RBAC behavior, role limits, audit semantics, and generic invalid-invite response so the endpoint does not become an invite-enumeration oracle.

GREEN / integration gate

Require focused API GREEN, full exact-current-head Server Tests/browser/owned coverage/docstrings, security/SAST/dependency evidence under the repository exact-head contract, and an independent current-head approval before integration. #589's current review thread must remain unresolved until this defect is actually protected-shipped or #589 is reconciled onto a protected base containing the fix.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority: highHigh-priority or P1 worktype: bugDefect or incorrect behavior

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions