VYPR
Unrated severityNVD Advisory· Published Jun 20, 2026

Capgo - App ID Confusion via ILIKE Wildcard in Preview Subdomain Lookup

CVE-2026-56325

Description

Capgo before 12.128.2 uses ILIKE pattern matching instead of exact matching for app_id lookup in the preview subdomain resolver, allowing underscore characters in app_id to act as SQL wildcards. Attackers can create apps with app_ids differing by one character at underscore positions to cause unintended pattern matches, breaking preview functionality for legitimate apps or causing app-id confusion.

AI Insight

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

Affected products

1

Patches

Vulnerability mechanics

Root cause

"Using PostgreSQL ILIKE pattern matching (instead of exact equality) for app_id lookup in the preview subdomain resolver, where the underscore character is a single-character wildcard."

Attack vector

An attacker creates a second app whose app_id differs from a victim app_id by exactly one character at the underscore position (e.g., `ee.forgr.capacitorXgo.new2` collides with `ee.forgr.capacitor_go.new2`). When the victim's preview domain is requested, the ILIKE query matches both rows, `.single()` fails, and the preview endpoint returns `app_not_found` even though the victim app exists and preview is enabled. The attacker only needs the ability to create apps in the same organization (or any organization where a colliding app_id can be registered) and does not need any special network position beyond normal API access [ref_id=1].

Affected code

The preview subdomain resolver in `supabase/functions/_backend/files/preview.ts` uses `.ilike('app_id', appId)` with `.single()`, and the app_id validation regex in `supabase/functions/_backend/utils/utils.ts` (`reverseDomainRegex = /^[a-z0-9]+(.[\w-]+)+$/i`) permits underscores (`_`). Because `_` is a single-character wildcard in PostgreSQL ILIKE, an app_id containing `_` becomes a pattern rather than a literal match, causing multi-row matches that break `.single()` and return `app_not_found` [ref_id=1].

What the fix does

The advisory recommends replacing `.ilike('app_id', appId)` with `.eq('app_id', appId)` to perform an exact match instead of a pattern match. To preserve case-insensitive lookup, the suggested approach is to store a normalized `app_id_lower` column and compare with `.eq('app_id_lower', appId.toLowerCase())`. Alternatively, escape LIKE wildcards (`_` and `%`) before using ILIKE, or disallow underscores in app_id entirely. The patch in version 12.128.2 implements one of these strategies so that underscores are treated as literal characters, eliminating unintended wildcard collisions [ref_id=1].

Preconditions

  • inputThe victim app must have an app_id containing at least one underscore character.
  • authThe attacker must be able to create a new app (in the same or a different organization) whose app_id differs from the victim's app_id only at the underscore position(s).
  • configThe victim app must have the preview feature enabled in the dashboard.

Reproduction

The advisory provides a full PoC using curl commands against the Capgo API. Steps: (1) identify an existing app with `_` in its app_id (e.g., `ee.forgr.capacitor_go.new2`); (2) create a partner app differing at the underscore position (e.g., `ee.forgr.capacitorXgo.new2`); (3) enable preview for the underscore app; (4) request the preview domain for the underscore app — it returns `app_not_found` (HTTP 400), while the partner app reaches a different gating response (`preview_disabled`). The exact API calls and encoded subdomain format are shown in the advisory [ref_id=1].

Generated on Jun 21, 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.