CVE-2026-100621
Executive Summary
CVE-2026-100621 is an incomplete access-control and content-lock enforcement flaw in Capgo (capgo.app), an open-source over-the-air (OTA) update platform for mobile applications. The flaw allows an attacker who holds a Capgo API key with bundle write/upload permission to keep or place an app_versions row in the r2-direct storage state and subsequently mutate delivery-critical metadata columns, bypassing the post-upload content immutability hardening that was added after a prior app_versions metadata-tampering issue. The impact is a low-severity integrity violation (CVSS 4.3) because altered bundle metadata — including checksum and session_key — is served to client devices through the /updates endpoint, enabling a privileged authenticated actor to tamper with OTA update metadata. All versions of the affected component are impacted and no patch is currently available.
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 interaction between a PostgreSQL Row Level Security/content-lock mechanism and the channel/version selection logic used by the OTA /updates endpoint, within the Capgo self-hosted backend.
Two distinct enforcement gaps combine to produce the issue:
Content-lock exemption for
r2-directrows: The content lock implemented byenforce_encrypted_bundle_trigger/check_encrypted_bundle_on_insertinsupabase/schemas/prod.sqlis designed to makeapp_versionsrows immutable after upload for a set of delivery-critical columns (name,app_id,session_key,key_id,storage_provider,r2_path,external_url,checksum,manifest,native_packages). However, this lock explicitly exempts rows whose previousstorage_providervalue isr2-direct. While a row remains in thatr2-directstate, those delivery-critical columns remain mutable.OTA selection not excluding
r2-directversions: The channel/version join used by the/updatesendpoint, located insupabase/functions/_backend/utils/pg.ts, filters out only deleted versions. It does not exclude rows in ther2-directstate. Consequently, anapp_versionsrow in ther2-directstate remains eligible for selection and delivery by the OTA/updatesendpoint.
Because these two conditions coexist, an attacker with a Capgo API key carrying bundle write/upload permission can:
- Create a new bundle version, or keep an existing one, in the
r2-directstate. - Assign that version to a channel so it is reachable by
/updates. - Issue direct PostgREST requests to modify the exempted delivery-critical columns (for example
checksumandsession_key).
The net effect is that altered bundle metadata is served to devices through /updates. The weakness class is CWE-284 (Improper Access Control) — the content-lock control is intended to enforce post-upload immutability, but the r2-direct state constitutes an enforcement gap that leaves the protected columns writable. This bypasses the immutability hardening added for a prior app_versions metadata-tampering issue.
Note: The NVD description does not disclose the exact PostgREST endpoint paths, table/column quoting, HTTP verbs, or the specific SQL statements used. This report therefore confines itself to the functions, files, columns, and endpoint names that appear verbatim in the description and does not infer unimplemented technical specifics.
Exploitation Scenarios
No public PoC or exploit code is available for CVE-2026-100621; the attack chain below is inferred from the vulnerability class (improper access control / incomplete content-lock enforcement) and the NVD description.
Reconnaissance and target identification: The attacker must first possess a Capgo API key that grants bundle write/upload permission. This implies a privileged, authenticated position (consistent with the CVSS
PR:Lrating) — for example, a developer, integration, or role that can manage OTA bundles. The attacker identifies the Capgo backend, including the/updatesOTA endpoint and the PostgREST interface used by the Supabase deployment (as referenced bysupabase/schemas/prod.sqlandsupabase/functions/_backend/utils/pg.ts).Triggering the specific flaw class: The attacker creates a new bundle version or ensures an existing
app_versionsrow is in ther2-directstate (by setting/retainingstorage_provider=r2-direct). Because the content lockenforce_encrypted_bundle_trigger/check_encrypted_bundle_on_insertexempts rows whose previousstorage_providerisr2-direct, the delivery-critical columns remain mutable for that row.Payload/execution method: The attacker assigns the affected version to a channel, ensuring the channel/version join used by
/updatesselects the row. The/updatesjoin filters only deleted versions and does not excluder2-directversions, so the row remains OTA-selectable. The attacker then issues direct PostgREST requests to modify the delivery-critical columns —name,app_id,session_key,key_id,storage_provider,r2_path,external_url,checksum,manifest,native_packages— after the upload/immutability window would normally have locked them. The description specifically calls out modifyingchecksumandsession_keyas examples.Post-exploitation impact: Devices requesting updates via
/updatesreceive the tampered bundle metadata (for example an alteredchecksumandsession_key). This constitutes an integrity violation of the update channel rather than a direct confidentiality or availability compromise, matching the CVSS vector (I:L, no C or A impact). The consequences depend on how downstream clients validate and apply the altered metadata; the description does not establish code-execution impact, so this report does not assert one.
Constraints: The attack requires a valid API key with bundle write/upload permission (PR:L, AC:L, AV:N, UI:N). No privilege escalation, user interaction, or scope change is involved (S:U).
Impact Assessment
CVE-2026-100621 carries a CVSS 3.1 base score of 4.3 (MEDIUM) with vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N. Interpretation of each metric:
- Attack Vector (Network, AV:N): The vulnerable interfaces — the
/updatesOTA endpoint and the PostgREST API — are network-reachable. - Attack Complexity (Low, AC:L): No special conditions or race windows are described; the
r2-directstate and the non-excluding join make the manipulation straightforward once the required permission is held. - Privileges Required (Low, PR:L): The attacker must hold a Capgo API key with bundle write/upload permission. This is a meaningful precondition that limits the population of potential attackers to authenticated, privileged users or compromised credentials/integrations.
- User Interaction (None, UI:N): No victim interaction is required to alter the metadata; delivery to devices via
/updatesoccurs as part of normal client polling. - Scope (Unchanged, S:U): The impact is confined to the Capgo-managed application update data model.
- Confidentiality (None, C:N): No data disclosure is described.
- Integrity (Low, I:L): Delivery-critical bundle metadata (e.g.,
checksum,session_key) can be altered after the normal immutability window, and the altered values are served to devices. - Availability (None, A:N): No denial-of-service effect is described.
Business impact: Organizations using Capgo for OTA delivery of mobile application bundles are exposed to integrity tampering of the update metadata stream. Because OTA update pipelines are a trusted channel into mobile endpoints, undetected metadata tampering undermines update integrity guarantees and could erode trust in the update mechanism. Blast radius is limited to environments where an actor already possesses bundle write/upload credentials — for example leaked, shared, or over-provisioned API keys, or compromised CI/integration credentials. The flaw affects all versions with no patch available, so exposure persists until upstream remediation or compensating controls are applied. No CISA KEV listing and no known in-the-wild exploitation are reported.
Detection Guidance
Sigma Rule
title: Capgo r2-direct Bundle Metadata Tampering Attempt
id: 8f2c9a41-6b7d-4e2a-9c3f-capgo100621
status: experimental
description: Detects direct PostgREST modification of delivery-critical app_versions columns for Capgo bundles in the r2-direct storage state (CVE-2026-100621).
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-100621
author: valtersit.com
date: 2026/01/01
logsource:
category: web
product: supabase
detection:
selection_endpoint:
http_method:
- 'PATCH'
- 'PUT'
url|contains:
- '/rest/v1/app_versions'
selection_columns:
request_body|contains:
- 'storage_provider'
- 'r2-direct'
- 'checksum'
- 'session_key'
- 'r2_path'
- 'manifest'
condition: selection_endpoint and selection_columns
fields:
- client_ip
- url
- http_method
- user_agent
falsepositives:
- Legitimate administrative bundle management by authorized operators
level: medium
tags:
- attack.t1190
- cve.2026-100621
YARA Rule
rule CVE_2026_100621_Capgo_R2Direct_Metadata_Tamper
{
meta:
description = "Detects direct PostgREST payloads targeting Capgo app_versions delivery-critical columns while storage_provider is r2-direct"
author = "valtersit.com"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-100621"
date = "2026-01-01"
severity = "medium"
strings:
$ep1 = "/rest/v1/app_versions" ascii nocase
$col1 = "storage_provider" ascii nocase
$col2 = "r2-direct" ascii nocase
$col3 = "checksum" ascii nocase
$col4 = "session_key" ascii nocase
$col5 = "r2_path" ascii nocase
$col6 = "manifest" ascii nocase
$col7 = "native_packages" ascii nocase
condition:
$ep1 and $col2 and 2 of ($col1, $col3, $col4, $col5, $col6, $col7)
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-100621 Capgo r2-direct app_versions metadata tampering via PostgREST"; flow:established,to_server; http.method; content:"PATCH"; http.uri; content:"/rest/v1/app_versions"; http.request_body; content:"storage_provider"; http.request_body; content:"r2-direct"; http.request_body; content:"checksum"; classtype:attempted-admin; reference:cve,2026-100621; reference:url,nvd.nist.gov/vuln/detail/CVE-2026-100621; sid:2026100621; rev:1;)
Elastic Detection
sequence by source.ip with maxspan=5m
[http where http.request.method in ("PATCH", "PUT")
and http.request.uri : "/rest/v1/app_versions"
and http.request.body.text : "storage_provider"
and http.request.body.text : "r2-direct"]
[http where http.request.method in ("PATCH", "PUT")
and http.request.uri : "/rest/v1/app_versions"
and (http.request.body.text : "checksum"
or http.request.body.text : "session_key"
or http.request.body.text : "r2_path"
or http.request.body.text : "manifest"
or http.request.body.text : "native_packages")]
Splunk SPL Query
index=web OR index=proxy
| search (http_method=PATCH OR http_method=PUT)
uri_path="/rest/v1/app_versions"
(request_body="*storage_provider*" OR request_body="*r2-direct*"
OR request_body="*checksum*" OR request_body="*session_key*"
OR request_body="*r2_path*" OR request_body="*manifest*"
OR request_body="*native_packages*")
| stats count min(_time) as first_seen max(_time) as last_seen
values(request_body) as bodies
by src_ip, uri_path, http_method
| where count >= 1
| convert ctime(first_seen) ctime(last_seen)
Wazuh OSSEC Rule
<group name="web,capgo,cve_2026_100621,">
<rule id="1006210" level="10">
<decoded_as>json</decoded_as>
<field name="http_method">PATCH|PUT</field>
<field name="url">/rest/v1/app_versions</field>
<field name="request_body">storage_provider</field>
<field name="request_body">r2-direct</field>
<description>CVE-2026-100621: Capgo bundle metadata tampering - r2-direct app_versions row modified via PostgREST</description>
<mitre>
<id>T1190</id>
</mitre>
</rule>
<rule id="1006211" level="12">
<decoded_as>json</decoded_as>
<field name="http_method">PATCH|PUT</field>
<field name="url">/rest/v1/app_versions</field>
<field name="request_body">checksum|session_key</field>
<description>CVE-2026-100621: Capgo delivery-critical column (checksum/session_key) mutation detected</description>
<mitre>
<id>T1190</id>
</mitre>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source).
Immediate mitigations (until vendor remediation):
- Restrict and audit PostgREST access to the
app_versionstable. Where possible, deny direct client-originatedPATCH/PUToperations againstapp_versionsand route all bundle mutations through controlled backend logic. - Tighten API key scope: remove bundle write/upload permission from any key that does not strictly require it. Rotate any API keys that have ever held bundle write/upload permission and that may have been shared or exposed.
- Detect and remove
r2-directversions from channels. While the flawed content-lock exemption and the/updatesjoin (insupabase/functions/_backend/utils/pg.ts) remain unfixed, keepingr2-directrows out of channel assignments reduces exposed surface. - Monitor for changes to delivery-critical columns (
name,app_id,session_key,key_id,storage_provider,r2_path,external_url,checksum,manifest,native_packages) on rows in ther2-directstate and alert on any post-upload mutation. - Deploy the detection rules in this report at the network, proxy, and application-log layers to catch direct PostgREST tampering attempts.
- Restrict and audit PostgREST access to the
Patch/upgrade steps:
- No vendor patch is available at the time of publication and all versions are affected. Monitor the Capgo project (capgo.app) and the upstream repository for an advisory or commit that (a) closes the
r2-directexemption inenforce_encrypted_bundle_trigger/check_encrypted_bundle_on_insertwithinsupabase/schemas/prod.sql, and (b) updates the channel/version join insupabase/functions/_backend/utils/pg.tsto excluder2-directversions from/updatesselection. - Because the flaw is data/schema and backend-function bound, self-hosted operators should treat any future release notes covering these two areas as the required upgrade trigger and validate that both enforcement points are corrected before considering the issue resolved.
- If the platform supports it, apply a local compensating database control (e.g., a trigger/constraint) that removes the
r2-directexemption so the delivery-critical columns are immutable regardless ofstorage_providerstate — only after reviewing consistency with legitimater2-directworkflows.
- No vendor patch is available at the time of publication and all versions are affected. Monitor the Capgo project (capgo.app) and the upstream repository for an advisory or commit that (a) closes the
Long-term hardening:
- Enforce least privilege on all Capgo API keys and enforce separation between bundle upload and bundle metadata modification permissions.
- Make the update-selection query deny-by-default: only explicitly permitted storage states should be selectable by
/updates, rather than filtering out a small deny-list (deleted-only) of states. - Add integrity verification on the client side so that served bundle metadata (notably
checksum,session_key,key_id) is cryptographically validated before being trusted. - Integrate continuous monitoring for post-upload mutation of delivery-critical columns and alert on any such change outside a defined change window.
References
- NVD entry for CVE-2026-100621: https://nvd.nist.gov/vuln/detail/CVE-2026-100621
- Capgo project homepage / advisories: https://capgo.app
- CWE-284 — Improper Access Control: https://cwe.mitre.org/data/definitions/284.html
- MITRE ATT&CK T1190 — Exploit Public-Facing Application: https://attack.mitre.org/techniques/T1190/
- FIRST EPSS (no score currently assigned for this CVE): https://www.first.org/epss/
No known threat actor campaigns and no exploit-in-the-wild evidence are associated with CVE-2026-100621 at the time of writing. No public PoC, Nuclei template, or exploit code is available. CISA KEV status: not listed.
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.