VYPR
Unrated severityNVD Advisory· Published Jun 20, 2026

Capgo - Unauthenticated Cross-Tenant Metrics Poisoning via upsert_version_meta RPC

CVE-2026-56213

Description

Capgo before 12.128.2 contains an authorization bypass vulnerability in the public.upsert_version_meta SECURITY DEFINER function exposed via PostgREST RPC, allowing unauthenticated attackers to insert arbitrary rows into version_meta for any app_id. Attackers can exploit this by calling the RPC endpoint with a public anon key to poison storage metrics, causing persistent false data in dashboards and triggering incorrect alerts across victim applications.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Affected products

1

Patches

Vulnerability mechanics

Root cause

"The PostgreSQL function `public.upsert_version_meta` is created as `SECURITY DEFINER`, granted to the `anon` role, and performs no authorization checks, allowing unauthenticated attackers to write arbitrary rows into `version_meta` for any `app_id`."

Attack vector

An unauthenticated attacker sends a POST request to `/rest/v1/rpc/upsert_version_meta` using the public Supabase anon key (the `sb_publishable_*` key) with attacker-controlled `p_app_id`, `p_version_id`, and `p_size` JSON parameters. The function is granted to the `anon` role and is `SECURITY DEFINER`, so it bypasses row-level security on `version_meta` and inserts the data without any authorization checks [ref_id=1]. This enables cross-tenant writes to any victim application's storage metadata.

Affected code

The vulnerability is in the Supabase PostgreSQL function `public.upsert_version_meta(p_app_id, p_version_id, p_size)` exposed as a PostgREST RPC endpoint. The function is defined as `SECURITY DEFINER` and is granted EXECUTE to the `anon` role ([ref_id=1]). It performs no authorization checks, allowing any caller to insert rows into `public.version_meta` for arbitrary `app_id` and `version_id` values without verifying ownership.

What the fix does

The advisory recommends removing the `EXECUTE` privilege on `public.upsert_version_meta` from the `anon` and `authenticated` roles, restricting it to `service_role` only. It also recommends adding explicit authorization inside the function: derive the caller's identity via `public.get_identity('{write,all}'::public.key_mode[])`, verify that the caller has rights to `p_app_id`, and confirm that `p_version_id` belongs to `p_app_id`. Additionally, the advisory suggests rejecting negative `p_size` values or enforcing strict bounds [ref_id=1]. The patch thus closes the privilege escalation path by removing public access and adding ownership checks.

Preconditions

  • networkThe attacker must have network access to the Supabase project's PostgREST endpoint and know the project URL.
  • inputThe attacker must possess the public Supabase anon key (`sb_publishable_*`), which is typically exposed in client-side applications.

Reproduction

The advisory includes a PoC that demonstrates the exploit [ref_id=1]. An attacker runs a shell script that calls `curl` against the RPC endpoint with the anon key and attacker-chosen `p_app_id`, `p_version_id`, and `p_size` values. The PoC shows the function returns `true` on the first insert (whether positive or negative size) and `false` on a duplicate insert, confirming arbitrary write capability for any app ID.

Generated on Jun 20, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

2

News mentions

0

No linked articles in our index yet.