CVE-2026-100619
Executive Summary
CVE-2026-100619 is a privilege escalation and data integrity vulnerability in Capgo (capgo.app), an open-source over-the-air (OTA) update platform for Capacitor applications. The flaw allows a principal with app-scoped upload/write/all API keys, or an authenticated user with write+ rights on an app, to indirectly bypass restrictive row-level security (RLS) policies on the public.manifest table by updating public.app_versions.manifest for versions using the r2-direct storage provider. This enables OTA manifest poisoning, where attacker-controlled file metadata is inserted into the public.manifest table via a trusted service-role async worker, ultimately serving malicious download URLs to clients through the /updates endpoint. With a CVSS score of 8.8 (High), this vulnerability poses a significant supply chain risk, potentially allowing attackers to distribute malicious updates to end-user applications.
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
Capgo's architecture relies on Supabase for backend services, utilizing row-level security (RLS) to enforce access controls on database tables. The public.manifest table is protected by a RESTRICTIVE RLS policy that blocks direct user inserts, ensuring only trusted processes can populate manifest entries. However, the public.app_versions table contains a manifest column that can be updated by users with write+ permissions on an app. The vulnerability arises from an inconsistency in the content-lock check: when a version's storage_provider is set to 'r2-direct', updates to app_versions.manifest are not covered by the bundle content-lock verification. An attacker with the requisite permissions can modify the manifest field of an app_versions record, injecting arbitrary values for file_name, file_hash, and s3_path.
The on_version_update async worker, which runs with service-role privileges, processes updates to app_versions. It trusts the record.manifest data and inserts the attacker-controlled file_name, file_hash, and s3_path into the public.manifest table before clearing the original app_versions.manifest field. Since the worker uses a service-role Supabase client, it bypasses the RESTRICTIVE RLS policy on public.manifest. When a channel subsequently points to the crafted version, the /updates endpoint retrieves the malicious manifest entry and returns it as a client-facing download_url. This allows the attacker to poison the OTA update manifest, directing clients to download arbitrary files, potentially leading to remote code execution or data exfiltration on end-user devices.
The vulnerability class is a combination of improper access control (CWE-266: Incorrect Privilege Assignment) and trust boundary violation. The attack surface includes the Capgo API endpoints for updating app versions and the /updates endpoint used by clients to check for updates. No public proof-of-concept or exploit code is available, but the attack chain is well-defined by the NVD description.
Exploitation Scenarios
Reconnaissance/Target Identification: The attacker identifies a Capgo instance (e.g., via Shodan dorks like
http.title:"Capgo"orhttp.html:"capgo.app"). They must obtain an API key with app-scoped upload/write/all permissions, or authenticate as a user with write+ rights on a target app. This could be achieved through credential theft, insider access, or by exploiting misconfigured permissions.Triggering the Flaw: The attacker sends an API request to update an app version's
manifestfield. They target a version whosestorage_provideris'r2-direct', as this configuration bypasses the bundle content-lock check. The request includes attacker-controlled values forfile_name,file_hash, ands3_pathwithin themanifestobject.Payload/Execution Method: The
on_version_updateasync worker automatically processes the update. Trusting therecord.manifest, it inserts the maliciousfile_name,file_hash, ands3_pathinto thepublic.manifesttable using a service-role client, which bypasses the RESTRICTIVE RLS policy. The worker then clearsapp_versions.manifest. The attacker's payload is now persisted in the manifest table.Post-Exploitation Impact: When a channel is configured to point to the crafted version, the
/updatesendpoint serves the attacker-controlled manifest entry as adownload_urlto clients. Clients performing OTA updates download the malicious file, which could be a crafted JavaScript bundle, a native binary, or any other file type. This can lead to remote code execution, data theft, or further lateral movement within the client environment. The attacker can distribute poisoned updates to all users of the affected app, effectively compromising the software supply chain.
Impact Assessment
The vulnerability has a CVSS v3.1 score of 8.8 (High), with the vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H. The attack is network-accessible (AV:N), requires low complexity (AC:L), and necessitates low privileges (PR:L) — specifically, a valid API key or authenticated user with write+ rights. No user interaction is required (UI:N). The scope is unchanged (S:U), meaning the vulnerable component and impacted component are the same. The impact on confidentiality, integrity, and availability is high (C:H/I:H/A:H). Successful exploitation allows an attacker to poison the OTA manifest, leading to the distribution of malicious updates to all clients of the affected app. This can result in widespread compromise of end-user devices, data breaches, and reputational damage. The blast radius includes any application using Capgo for OTA updates, potentially affecting thousands of users per app. Since no patch is available, all versions are vulnerable, and the risk is amplified by the lack of a public PoC (reducing the likelihood of immediate exploitation but not the potential impact).
Detection Guidance
Sigma Rule
title: Capgo OTA Manifest Poisoning via App Version Update
id: 3a4b5c6d-7e8f-9a0b-1c2d-3e4f5a6b7c8d
status: experimental
description: Detects updates to Capgo app_versions.manifest with r2-direct storage provider, indicating potential CVE-2026-100619 exploitation.
author: Threat Intelligence Team
date: 2026-01-01
logsource:
product: supabase
service: postgres
detection:
selection:
event: "UPDATE"
table: "app_versions"
column: "manifest"
filter:
storage_provider: "r2-direct"
condition: selection and filter
falsepositives:
- Legitimate updates by authorized users
level: high
tags:
- attack.t1190
- cve.2026.100619
YARA Rule
rule CVE_2026_100619_Capgo_Manifest_Poisoning
{
meta:
description = "Detects malicious manifest entries for Capgo OTA poisoning"
author = "Threat Intelligence Team"
date = "2026-01-01"
reference = "CVE-2026-100619"
severity = "high"
strings:
$s1 = "r2-direct" ascii wide nocase
$s2 = "public.manifest" ascii wide nocase
$s3 = "file_name" ascii wide nocase
$s4 = "file_hash" ascii wide nocase
$s5 = "s3_path" ascii wide nocase
$s6 = "on_version_update" ascii wide nocase
condition:
any of them
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-100619 Capgo OTA Manifest Poisoning Attempt"; flow:to_server,established; content:"POST"; http_method; content:"/api/app_versions"; http_uri; content:"manifest"; http_client_body; content:"r2-direct"; http_client_body; content:"file_name"; http_client_body; content:"file_hash"; http_client_body; content:"s3_path"; http_client_body; reference:cve,2026-100619; classtype:attempted-user; sid:1000001; rev:1;)
Elastic Detection
sequence by user.id with maxspan=5m
[ database where event.action == "update" and table.name == "app_versions" and column.name == "manifest" and storage_provider == "r2-direct" ]
[ database where event.action == "insert" and table.name == "public.manifest" and process.name == "on_version_update" ]
Splunk SPL Query
index=supabase_logs sourcetype=postgres:query
| search (action="UPDATE" table="app_versions" column="manifest" storage_provider="r2-direct")
| join type=inner user_id [
search index=supabase_logs sourcetype=postgres:query (action="INSERT" table="public.manifest" process="on_version_update")
]
| table _time user_id table column storage_provider file_name file_hash s3_path
| sort - _time
Wazuh OSSEC Rule
<group name="capgo,">
<rule id="100100" level="12">
<decoded_as>json</decoded_as>
<field name="table">app_versions</field>
<field name="column">manifest</field>
<field name="storage_provider">r2-direct</field>
<description>CVE-2026-100619: Capgo app_versions.manifest update with r2-direct storage provider detected</description>
<mitre>
<id>T1190</id>
</mitre>
</rule>
<rule id="100101" level="12">
<decoded_as>json</decoded_as>
<field name="table">public.manifest</field>
<field name="process">on_version_update</field>
<description>CVE-2026-100619: Suspicious insert into public.manifest by on_version_update worker</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:
- Restrict API keys and user permissions: Audit and minimize the number of principals with app-scoped upload/write/all API keys or write+ rights on apps. Enforce least privilege.
- Disable
r2-directstorage provider: If not essential, change thestorage_providerfor existing app versions to a provider covered by the bundle content-lock check, or temporarily disable ther2-directoption. - Monitor and alert: Implement the detection rules above to identify anomalous updates to
app_versions.manifestor inserts intopublic.manifest. - Network segmentation: Restrict access to Capgo API endpoints to trusted IP ranges where possible.
Patch/Upgrade Steps:
- No vendor patch is available. Monitor the Capgo GitHub repository and official channels for security advisories and updates. Once a patch is released, apply it immediately following standard change management procedures.
- If a patched version becomes available, verify that it enforces content-lock checks for all storage providers and that the
on_version_updateworker validates the integrity of the manifest data before insertion.
Long-Term Hardening:
- Implement additional server-side validation for all fields inserted into
public.manifest, regardless of the source. - Adopt a zero-trust architecture: Never trust client-supplied data, even from authenticated users. Validate and sanitize all inputs.
- Conduct regular security audits of RLS policies and async workers to ensure privilege boundaries are correctly enforced.
- Consider implementing code signing for OTA updates to ensure clients only execute trusted code.
- Implement additional server-side validation for all fields inserted into
References
- NVD Entry: https://nvd.nist.gov/vuln/detail/CVE-2026-100619
- Capgo Official Website: https://capgo.app
- Capgo GitHub Repository: https://github.com/Cap-go/capgo
- CWE-266: Incorrect Privilege Assignment: https://cwe.mitre.org/data/definitions/266.html
- MITRE ATT&CK T1190: Exploit Public-Facing Application: https://attack.mitre.org/techniques/T1190/
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.