Summary
Capgo exposes its legacy organization-membership table through Supabase PostgREST with authorization policies that verify organization-admin status but omit invitation and role-consistency checks. An authenticated organization administrator may therefore add an existing user as an active administrator or modify membership records without using the intended invitation and role-assignment workflow.
Affected context
The issue occurs in Capgo deployments where the legacy public.org_users table is directly accessible through Supabase PostgREST and its insert or update policies rely only on administrator rights in the target organization. Risk is increased when the table remains writable without requiring invitation acceptance, target-user involvement, membership validation, or anti-escalation checks from the standard RBAC workflow.
Exploit preconditions
- Attack surface: Supabase PostgREST access to the legacy
public.org_userstable - Required access: An authenticated account with administrator rights in the target organization
- Trigger point: Direct insertion or modification of an organization-membership row
- Why exploitation is possible: The row-level policies authorize the organization administrator but do not enforce the invitation, acceptance, membership-consistency, or role-assignment controls used by the intended workflow
Why this happens
The underlying flaw is an authorization design gap. The database policies treat administrative authority over an organization as sufficient to create or modify membership records, while omitting authorization invariants enforced elsewhere in the application.
This maps to CWE-863: Incorrect Authorization, because the access-control decision does not fully enforce the conditions required for the requested operation. The insecure pattern is exposing a sensitive membership table through a direct data API while applying narrower checks than those used by the application's canonical RBAC path.
Potential impact
- An attacker with organization-admin rights could add existing users without their acceptance
- A user could be granted administrative membership without the intended role-assignment process
- Unauthorized users may gain access to organization and application data
- Membership records could be manipulated to undermine role governance and auditability
- The organization could experience privilege escalation or access-control bypass
General mitigation guidance
Mitigation generally focuses on consolidating membership changes behind one consistently enforced authorization path.
Common defensive patterns include:
- Restricting direct client access to legacy membership tables
- Enforcing invitation acceptance and target-user consent where required
- Applying the same membership, role-consistency, and anti-escalation checks to every write path
- Using database functions or service-layer operations with centralized authorization logic
- Preventing administrators from granting privileges beyond their permitted role scope
- Applying least privilege to database roles, API policies, and service accounts
- Preserving auditable records for membership and role changes
How teams detect issues like this
Organizations can identify similar authorization gaps through:
- Static and policy analysis of row-level security expressions
- Code review checks for direct writes to membership, role, or entitlement tables
- Comparison of authorization rules across UI, API, database, and background-job paths
- Tests that verify invitation, consent, role-boundary, and anti-escalation requirements for every mutation route
- PostgREST or API policy monitoring for unexpected membership inserts and privilege changes
- Automated security review tools that flag sensitive tables exposed with incomplete write predicates

