Capgo - Cross-Tenant Authorization Bypass via PostgREST Webhook Access
Description
Capgo before 12.128.2 contains a cross-tenant authorization bypass vulnerability in PostgREST endpoints that allows org-scoped read API keys to access other tenants' webhook secrets and delivery logs. Attackers can query the webhooks and webhook_deliveries endpoints to exfiltrate HMAC signing secrets and delivery payloads, enabling forged webhook events against victim organizations.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Affected products
1Patches
Vulnerability mechanics
Root cause
"PostgREST row-level security (RLS) policies on the webhooks and webhook_deliveries tables do not enforce the org-scoping constraint from the API key's limited_to_orgs claim, allowing a read-mode key restricted to one tenant to query rows belonging to another tenant."
Attack vector
An attacker with a Capgo read API key scoped to ORG_A (limited_to_orgs=[ORG_A]) sends authenticated HTTP requests to the Supabase PostgREST endpoints /rest/v1/webhooks and /rest/v1/webhook_deliveries, using the victim ORG_B's org ID in the `org_id=eq.$ORG_B` filter. The request includes the `apikey` (anon key), `authorization: Bearer` (anon key), and `capgkey` (the attacker's read-mode key) headers. Despite the key being scoped to ORG_A, the server returns rows containing ORG_B's webhook secrets (`whsec_*`), delivery payloads (`request_payload`), and response bodies (`response_body`), as demonstrated in the PoC [ref_id=1].
Affected code
The affected tables are `public.webhooks` (which exposes the `secret` column) and `public.webhook_deliveries` (which exposes `request_payload` and `response_body`). The RLS policies `"Allow org members to select webhooks"` and `"Allow org members to select webhook_deliveries"` use `check_min_rights('read', get_identity(...), org_id, ...)` but do not validate that the `org_id` in the returned row is within the API key's `limited_to_orgs` scope [ref_id=1].
What the fix does
The advisory states the fix is in version 12.128.2 but does not publish a specific patch diff. The remediation must ensure that PostgREST RLS policies on `public.webhooks` and `public.webhook_deliveries` enforce the `limited_to_orgs` claim from the API key, preventing a key scoped to ORG_A from returning rows where `org_id` belongs to ORG_B. Additionally, column-level security should be applied to `webhooks.secret` to prevent its exposure through direct table access [ref_id=1].
Preconditions
- authAttacker must possess a valid Capgo read-mode API key that is scoped to any one organization (limited_to_orgs set).
- networkAttacker must have network access to the target Supabase PostgREST endpoint (e.g., https://xvwzpoazmxkqosrdewyv.supabase.co).
- inputAttacker must know or enumerate the victim organization's UUID (org_id) and the target webhook/delivery row IDs.
Reproduction
1. Set environment variables: `SUPA` (Supabase URL), `ANON` (anon publishable key), `READKEY` (read-mode API key scoped to ORG_A), `ORG_B` (victim org UUID), `FOREIGN_WEBHOOK_ID`, `FOREIGN_DELIVERY_ID` (target row IDs). 2. Query ORG_B's webhooks: `curl -sk --http2 -i "$SUPA/rest/v1/webhooks?select=id&org_id=eq.$ORG_B" -H "apikey: $ANON" -H "authorization: Bearer $ANON" -H "capgkey: $READKEY"` — observe HTTP 200 returning rows for ORG_B. 3. Exfiltrate the webhook secret: `curl -sk --http2 -i "$SUPA/rest/v1/webhooks?id=eq.$FOREIGN_WEBHOOK_ID&select=id,org_id,name,url,secret,created_at" -H "apikey: $ANON" -H "authorization: Bearer $ANON" -H "capgkey: $READKEY"` — observe the `secret` field containing `whsec_*`. 4. Exfiltrate delivery logs: `curl -sk --http2 -i "$SUPA/rest/v1/webhook_deliveries?id=eq.$FOREIGN_DELIVERY_ID&select=id,org_id,webhook_id,event_type,status,request_payload,response_status,response_body,created_at" -H "apikey: $ANON" -H "authorization: Bearer $ANON" -H "capgkey: $READKEY"` — observe `request_payload` and `response_body` from ORG_B [ref_id=1].
Generated on Jun 20, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
2- github.com/Cap-go/capgo/security/advisories/GHSA-hj3h-v877-g5rxmitrevendor-advisory
- www.vulncheck.com/advisories/capgo-cross-tenant-authorization-bypass-via-postgrest-webhook-accessmitrethird-party-advisory
News mentions
0No linked articles in our index yet.