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:
- a
viewer/ordinary member roster response never contains invite token values;
- an authenticated account whose normalized email does not match the pending invite receives the existing stable invalid-invite response and gains no membership;
- the intended invited account can still accept exactly once and receives the invited role;
- used/missing tokens retain current fail-closed behavior;
- 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.
Protected-shipped defect
Fresh protected
develop@2c328875e00e86537df3e965170be80532571cadcurrently exposes pending invite bearer tokens throughGET /api/orgs/:id/membersto any organization member (includingviewer) and acceptsPOST /api/invites/:token/acceptfor 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:
viewer/ordinary member roster response never contains invitetokenvalues;Smallest causal repair
tokenfrom the pending-invite projection returned by the members endpoint.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.