CVE-2026-100616
Executive Summary
CVE-2026-100616 is a broken authorization vulnerability (CWE-863) in capgo.app, an over-the-air (OTA) update platform for Capacitor apps. An authenticated organization admin holding the org.update_settings permission can send a crafted update directly to the Supabase PostgREST interface to modify the customer_id column in the public.orgs table—a field the official organization update endpoint deliberately excludes from its allowlist. This allows an admin who lacks the org.update_billing permission to null or corrupt the organization's Stripe billing pointer, causing plan and billing checks to fail and effectively downgrading the organization to an unpaid/no-plan state. No patched version was available at the time of the advisory.
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
Technical Analysis
The vulnerability resides in the Row-Level Security (RLS) policy governing the UPDATE operation on the public.orgs table within capgo.app's Supabase backend. The RLS policy permits an organization admin—defined as a user holding the org.update_settings permission—to update the entire row, including the internal billing pointer column customer_id. This is a classic broken-access-control / insecure-direct-object-property class flaw, where the database authorization layer is broader than the application authorization layer.
The application-layer controls are intended to be layered: the official organization update endpoint (supabase/functions/_backend/public/organization/put.ts) implements a field allowlist that includes only a small set of editable settings fields and explicitly excludes customer_id. Separately, the private Stripe billing route is designed to require the org.update_billing permission. The defect is that these application-layer restrictions are not enforced at the data layer. Because Supabase exposes PostgREST as a first-class data API, an authenticated org admin can bypass the official endpoint entirely and issue UPDATE requests directly against the public.orgs table. The database RLS policy authorizes the write solely on the basis of org.update_settings, so the request succeeds even though the field being written (customer_id) is intended to be modifiable only through the billing-permission-gated route.
The result is a state-integrity failure: orgs.customer_id is the pointer that downstream plan and billing checks trust to determine whether an organization is on a valid paid plan. By nulling or corrupting this value, the attacker moves the organization from a valid paid plan state into unpaid/no-plan behavior. Notably, this is not a direct data breach—there is no confidentiality impact (C:N) and only a low integrity impact (I:L)—but the availability impact is high (A:H) because trusted billing state becomes unusable, degrading the organization's access to services that depend on plan validation.
The CVSS v3.1 vector (AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:L/A:H) reflects a network-reachable issue with low attack complexity and no user interaction, but a high privilege prerequisite (an authenticated admin). The scope is unchanged, confidentiality is unaffected, integrity is limited to the single trusted field, and availability is high due to the billing-state failure mode.
Exploitation Scenarios
No public PoC or exploit code is available; the attack chain below is inferred from the vulnerability class and the affected components named in the advisory.
Reconnaissance / Target Identification. The attacker identifies a capgo.app organization in which they hold an org admin role and possess the
org.update_settingspermission, but do not possessorg.update_billing. The attacker enumerates the target's Supabase endpoint and confirms that thepublic.orgstable is exposed through PostgREST—the standard data access surface for Supabase deployments.Triggering the Flaw Class. Because the RLS
UPDATEpolicy onpublic.orgsauthorizes writes based on theorg.update_settingspermission alone, the attacker does not need to route the request through the allowlisting endpointsupabase/functions/_backend/public/organization/put.ts. Instead, the attacker issues anUPDATEstatement directly to the Supabase PostgREST interface against thepublic.orgsrow for their organization.Payload / Execution Method. At the vulnerability-class level, the payload is a direct field write that targets the
customer_idcolumn—a field that the official endpoint explicitly excludes from its editable allowlist and that the private Stripe billing route gates behindorg.update_billing. The attacker setscustomer_idto a null value or an arbitrary/corrupt value. The database accepts the write because the RLS policy does not restrict which columns may be modified, only who may modify the row.Post-Exploitation Impact. Downstream application logic that trusts
orgs.customer_idto validate plan and billing status now fails or misbehaves. The organization transitions from a valid paid plan state to unpaid/no-plan behavior. Because this is an administrative self-tampering scenario, the primary impact is denial of the organization's own paid-plan functionality and integrity corruption of the billing pointer—not lateral compromise or data exfiltration.
Impact Assessment
The blast radius is scoped to individual organizations whose admins hold org.update_settings without org.update_billing. The integrity impact (I:L) is limited to the customer_id billing pointer; the confidentiality impact is none (C:N), as no data is disclosed. The availability impact (A:H) is the dominant concern: once customer_id is nulled or corrupted, plan and billing checks that trust the value fail, and the organization is moved from a valid paid plan state to unpaid/no-plan behavior. This can disable plan-gated functionality, disrupt billing reconciliation, and require manual remediation by the platform operator. Because the attacker already holds an administrative role, the vulnerability is chiefly an authorization-boundary bypass (privilege separation failure) rather than an external initial-access vector. The CVSS base score of 5.5 (Medium) is consistent with a high-privilege, integrity-and-availability-only impact. No EXACT/EPSS score has been published by FIRST.org; do not assume an EPSS value.
Detection Guidance
Sigma Rule
title: Direct Supabase PostgREST Update to orgs.customer_id Bypassing Billing Permission
id: 7c3f9a2e-6b1d-4e8f-9a0c-2f5d8e1b7c44
status: experimental
description: Detects direct PostgREST UPDATE requests targeting the public.orgs table that modify the customer_id billing pointer, indicating CVE-2026-100616 exploitation.
logsource:
category: web
product: supabase
detection:
selection_table:
request_path|contains:
- '/rest/v1/orgs'
selection_method:
request_method: 'PATCH'
selection_field:
request_body|contains: 'customer_id'
condition: selection_table and selection_method and selection_field
falsepositives:
- Legitimate billing service writes routed through authorized backend functions
level: high
tags:
- attack.t1565.001
- cve.2026-100616
YARA Rule
rule CVE_2026_100616_PostgREST_CustomerID_Tamper
{
meta:
description = "Detects requests or artifacts referencing direct tampering with orgs.customer_id via PostgREST"
author = "Threat Intelligence"
reference = "CVE-2026-100616"
date = "2026-01-01"
severity = "high"
strings:
$postgrest = "/rest/v1/orgs" ascii nocase
$table = "public.orgs" ascii nocase
$col = "customer_id" ascii nocase
$endpoint = "public/organization/put.ts" ascii nocase
condition:
(uint16(0) == 0x0a0a or uint16(0) == 0x0d0d or true) and
(($postgrest or $table) and $col) or ($endpoint and $col)
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-100616 - Direct PostgREST UPDATE tampering with orgs.customer_id"; flow:established,to_server; http.method; content:"PATCH"; http.uri; content:"/rest/v1/orgs"; http.request_body; content:"customer_id"; reference:cve,2026-100616; reference:url,https://nvd.nist.gov/vuln/detail/CVE-2026-100616; classtype:attempted-admin; sid:2026100616; rev:1;)
Elastic Detection
sequence by user.id with maxspan=5m
[http where http.request.method == "PATCH"
and stringContains(http.request.path, "/rest/v1/orgs")]
[http where stringContains(http.request.body, "customer_id")]
Splunk SPL Query
index=web sourcetype=supabase_access
| search http_method=PATCH uri_path="/rest/v1/orgs*"
| where match(request_body, "(?i)customer_id")
| stats count min(_time) as first_seen max(_time) as last_seen
values(user) as users, values(src_ip) as src_ips
by uri_path, request_body
| where count > 0
| convert ctime(first_seen) ctime(last_seen)
Wazuh OSSEC Rule
<group name="supabase,cve-2026-100616,">
<rule id="100616" level="12">
<decoded_as>json</decoded_as>
<field name="http_method">PATCH</field>
<field name="uri_path">/rest/v1/orgs</field>
<regex field="request_body">customer_id</regex>
<description>CVE-2026-100616 - Direct PostgREST UPDATE to orgs.customer_id detected; possible billing pointer tampering by org admin.</description>
<mitre>
<id>T1565.001</id>
</mitre>
<group>attack,tampering,</group>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source). No vendor fix, workarounds, or affected version list were published at the time of the advisory.
Immediate mitigations. Restrict the RLS
UPDATEpolicy onpublic.orgsso that it does not authorize writes to thecustomer_idcolumn based onorg.update_settingsalone. Where feasible, split the policy so that modifications to billing-related columns require theorg.update_billingpermission (or are limited to server-side service roles). Monitor Supabase/PostgREST access logs for directPATCH/UPDATErequests againstpublic.orgsthat includecustomer_idin the request body, and alert on any such request that does not originate from the authorized billing route.Patch/upgrade steps. No patched version exists. Organizations must track capgo.app advisories and apply the vendor fix as soon as it is released. Until then, treat the database-layer RLS policy as the primary compensating control.
Long-term hardening. Enforce column-level authorization in the data layer so that application-layer allowlists (as implemented in
supabase/functions/_backend/public/organization/put.ts) cannot be bypassed through direct PostgREST access. Adopt a defense-in-depth model in which sensitive columns such as billing pointers are writable only by trusted server-side roles, never by client-authenticated admin sessions. Audit all RLS policies for similar over-broad row-level grants that permit modification of fields gated behind stricter permissions elsewhere.
References
- NVD — CVE-2026-100616: https://nvd.nist.gov/vuln/detail/CVE-2026-100616
- CWE-863 — Incorrect Authorization: https://cwe.mitre.org/data/definitions/863.html
- Supabase — Row Level Security documentation: https://supabase.com/docs/guides/auth/row-level-security
- Supabase — PostgREST data API documentation: https://supabase.com/docs/guides/api
- capgo.app — official project advisories (vendor channel; no patched version was available at the time of the advisory)
No CISA KEV entry, no public PoC/exploit code, and no known threat-actor campaigns or exploit-in-the-wild evidence were reported for this CVE at the time of writing.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.