Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-56226

CVE-2026-56226: Capgo Information Disclosure Vulnerability

CVE-2026-56226 is an information disclosure vulnerability in Capgo that allows unauthenticated attackers to access user organization data and PII. This article covers technical details, affected versions, and mitigations.

Published:

CVE-2026-56226 Overview

CVE-2026-56226 is an information disclosure vulnerability in Capgo (Cap-go/capgo) versions prior to 12.128.2. The application exposes the Supabase PostgREST remote procedure call (RPC) function public.get_orgs_v6(userid uuid) with SECURITY DEFINER privileges granted to the anon role. The function accepts a caller-supplied user UUID without verifying it matches the authenticated user. An attacker holding only the public publishable API key can query POST /rest/v1/rpc/get_orgs_v6 with any user UUID to retrieve that user's organization membership, roles, subscription and trial metadata, and management_email personally identifiable information (PII). The vulnerability is classified under [CWE-200] Exposure of Sensitive Information to an Unauthorized Actor.

Critical Impact

Unauthenticated attackers can enumerate organizational data and PII for any Capgo user by supplying arbitrary UUIDs to a publicly reachable RPC endpoint.

Affected Products

  • Capgo (Cap-go/capgo) versions before 12.128.2
  • Self-hosted Capgo deployments exposing the Supabase PostgREST API
  • Any Capgo instance where the get_orgs_v6 RPC is granted to the anon role

Discovery Timeline

  • 2026-07-08 - CVE-2026-56226 published to the National Vulnerability Database (NVD)
  • 2026-07-08 - Last updated in NVD database

Technical Details for CVE-2026-56226

Vulnerability Analysis

Capgo integrates with Supabase and exposes PostgREST RPC endpoints for client applications. The RPC function public.get_orgs_v6(userid uuid) is defined with SECURITY DEFINER, meaning it executes with the privileges of its owner rather than the caller. The function is also granted to the anon PostgREST role, which represents unauthenticated clients that possess only the public publishable API key.

Because the publishable key is embedded in client-side code and mobile applications, any attacker who inspects a Capgo client can extract it. Once the attacker has the key, they can issue direct HTTP requests to the Supabase REST layer. The get_orgs_v6 function does not compare the supplied userid against auth.uid() or otherwise validate that the caller is authorized to view the target user's records.

Root Cause

The root cause is missing authorization inside a SECURITY DEFINER PostgreSQL function that accepts a user identifier as a parameter. The design pattern relies on the caller providing a trusted UUID, but PostgREST exposes the function to the anon role without server-side identity binding. Combined, these two decisions collapse the tenant isolation boundary in the multi-tenant model.

Attack Vector

An attacker retrieves the public publishable API key from the Capgo client or documentation. The attacker then sends POST /rest/v1/rpc/get_orgs_v6 requests with a JSON body containing a target userid UUID and the apikey header set to the publishable key. UUIDs can be obtained through enumeration, prior data leaks, or public references. Each successful response returns the target user's organization memberships, assigned roles, subscription and trial state, and the management_email field. No authentication, user interaction, or elevated privileges are required, and the attack is fully network-reachable.

See the GitHub Security Advisory and the VulnCheck Advisory for further technical detail.

Detection Methods for CVE-2026-56226

Indicators of Compromise

  • Repeated POST requests to /rest/v1/rpc/get_orgs_v6 from a small number of source IPs.
  • Requests to get_orgs_v6 carrying only the apikey header without a corresponding Authorization: Bearer JWT.
  • High-volume enumeration patterns where request bodies contain sequential or algorithmically generated UUID values.
  • Anomalous egress volume from the Supabase PostgREST endpoint tied to the anon role.

Detection Strategies

  • Parse PostgREST or reverse-proxy access logs and alert when unauthenticated clients invoke get_orgs_v6.
  • Query PostgreSQL audit logs for executions of public.get_orgs_v6 where auth.uid() is NULL or does not equal the supplied userid argument.
  • Baseline normal RPC call rates per API key and flag deviations that indicate scraping.

Monitoring Recommendations

  • Enable PostgreSQL statement logging for SECURITY DEFINER functions in the public schema.
  • Forward Supabase edge and PostgREST logs to a centralized analytics platform for retention and correlation.
  • Track distinct UUIDs supplied to get_orgs_v6 per source IP over rolling windows to identify enumeration.

How to Mitigate CVE-2026-56226

Immediate Actions Required

  • Upgrade Capgo to version 12.128.2 or later on all self-hosted deployments.
  • Revoke EXECUTE on public.get_orgs_v6(uuid) from the anon role until the upgrade is applied.
  • Rotate the Supabase publishable and service role keys if abuse is suspected.
  • Review PostgREST logs for prior invocations of get_orgs_v6 and notify affected users if PII was retrieved.

Patch Information

The maintainers of Capgo released version 12.128.2, which remediates CVE-2026-56226. The fix removes unauthenticated access to get_orgs_v6 and enforces that the caller-supplied UUID matches the authenticated auth.uid(). Deployment details are documented in the GitHub Security Advisory GHSA-m7mm-35v3-82f4.

Workarounds

  • Revoke the function grant from the anon role and restrict execution to the authenticated role only.
  • Rewrite the function body to derive the user identifier from auth.uid() instead of a parameter.
  • Place a Web Application Firewall (WAF) rule in front of /rest/v1/rpc/get_orgs_v6 that blocks requests lacking a valid JWT Authorization header.
bash
# Configuration example: revoke anon access and restrict to authenticated users
psql -h <supabase-host> -U postgres -d postgres <<'SQL'
REVOKE EXECUTE ON FUNCTION public.get_orgs_v6(uuid) FROM anon;
REVOKE EXECUTE ON FUNCTION public.get_orgs_v6(uuid) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.get_orgs_v6(uuid) TO authenticated;
SQL

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.