Skip to main content

Langflow CVE-2026-55255

CRITICAL
Authorization Bypass Through User-Controlled Key (CWE-639)
2026-06-19 https://github.com/langflow-ai/langflow GHSA-qrpv-q767-xqq2
9.9
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
9.9 CRITICAL
AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:L
vuln.today AI
9.9 CRITICAL

Network API endpoint, no user interaction, requires any authenticated API key (PR:L); scope changes because one tenant's auth reaches another tenant's flow, exposing data (C:H), letting attacker drive flow behavior (I:H), and consuming victim quota (A:L).

3.1 AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:L
4.0 AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:L

Primary rating from GitHub Advisory.

CVSS VectorGitHub Advisory

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:L
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Confidentiality
High
Integrity
High
Availability
Low

Lifecycle Timeline

3
Source Code Evidence Fetched
Jun 19, 2026 - 23:33 vuln.today
Analysis Generated
Jun 19, 2026 - 23:33 vuln.today
CVE Published
Jun 19, 2026 - 21:16 github-advisory
CRITICAL 9.9

DescriptionGitHub Advisory

Summary

Insecure Direct Object Reference (IDOR) vulnerability in /api/v1/responses endpoint allows an authenticated attacker to execute any flow belonging to another user by specifying the victim's flow ID in the request.

Details

The vulnerability exists in the get_flow_by_id_or_endpoint_name helper function in src/backend/base/langflow/helpers/flow.py (lines 399-414).

When a flow is accessed via UUID (flow_id), the function queries the database directly without verifying if the authenticated user owns that flow:

python
# src/backend/base/langflow/helpers/flow.py:399-414
async def get_flow_by_id_or_endpoint_name(flow_id_or_name: str, user_id: str | UUID | None = None) -> FlowRead:
    async with session_scope() as session:
        try:
            flow_id = UUID(flow_id_or_name)
# When using UUID, query directly WITHOUT checking user_id
            flow = await session.get(Flow, flow_id)
# ❌ No user_id check!
        except ValueError:
            endpoint_name = flow_id_or_name
            stmt = select(Flow).where(Flow.endpoint_name == endpoint_name)
# Only when using endpoint_name is user_id checked
            if user_id:
                stmt = stmt.where(Flow.user_id == uuid_user_id)

This function is used by the /api/v1/responses endpoint (defined in src/backend/base/langflow/api/v1/openai_responses.py:589).

PoC (Proof of Concept)

bash
# Attacker (user A) with API_KEY_A tries to execute victim (user B)'s flow
curl -X POST "http://localhost:7860/api/v1/responses" \
  -H "x-api-key: sk-ATTACKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "VICTIM_FLOW_ID",
    "input_value": "test",
    "stream": false
  }'
# Returns 200 and executes the victim's flow

Impact

Any authenticated user can:

  1. Execute any flow in the system by knowing its flow ID
  2. Access potentially sensitive data processed by victim's flows
  3. Consume victim's resources

Fixes

Fixed in PR #12832 (fix(security): close IDOR in get_flow_by_id_or_endpoint_name), merged 2026-04-22, released in Langflow 1.9.1.

The helper normalizes user_id once and enforces ownership on both lookup branches (UUID *and* endpoint_name):

python
flow_id = UUID(flow_id_or_name)
flow = await session.get(Flow, flow_id)
if flow is not None and uuid_user_id is not None and flow.user_id != uuid_user_id:
    flow = None
# cross-user lookup falls through to the shared 404

Key points:

  • Cross-user lookups return 404 (not 403), so flow existence is not disclosed via a 403-vs-404 oracle.
  • /api/v1/responses and /api/v2/workflow pass user_id explicitly, so fixing the helper closes them directly; the /api/v1/run* routes were additionally moved from a bare Depends(get_flow_by_id_or_endpoint_name) to auth-aware wrapper dependencies (defense in depth).
  • A malformed user_id now fails closed (404 instead of a raw 500).
  • Webhook routes intentionally keep the unscoped lookup (public by design / explicit ownership check elsewhere).
  • Regression tests cover the cross-user UUID case and reproduce the original PoC against /api/v1/responses.

Acknowledgements

Thanks to the security researchers who responsibly disclosed this vulnerability:

  • @yzeirnials
  • @johnatzeropath
  • @LeftenantZero
  • @Zwique

AnalysisAI

Cross-user flow execution in Langflow versions prior to 1.9.1 allows any authenticated API user to run another user's flows by submitting the victim's flow UUID to the /api/v1/responses endpoint. The flaw stems from a missing ownership check in the get_flow_by_id_or_endpoint_name helper, with a working PoC published in the GHSA advisory; no public exploit identified at time of analysis in the form of mass exploitation, and it is not listed in CISA KEV.

Unlock full vulnerability intelligence

  • Risk assessment & exploitation conditions
  • Attack chain visualization
  • Remediation with exact patch versions
  • Threat intelligence from 22 sources
  • Personal watchlist & email alerts

Free forever · No credit card required

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata

Access
Obtain low-privilege API key on Langflow instance
Delivery
Discover victim flow UUID via leak or oracle
Exploit
POST UUID as model to /api/v1/responses
Execution
Helper resolves flow without ownership check
Persist
Victim's flow executes under attacker control
Impact
Exfiltrate output and abuse victim's integrations

Vulnerability AssessmentAI

Exploitation Requires (1) network reach to a Langflow instance running a version below 1.9.1, (2) a valid API key or session for any user on that instance (PR:L), and (3) knowledge of a target flow's UUID - either guessed through leakage channels or harvested via the pre-patch 403-vs-404 existence oracle on /api/v1/run*. … Additional conditions and limiting factors are described in the full assessment.
Risk Assessment The vendor CVSS 3.1 score of 9.9 (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:L) reflects network-reachable, low-privilege exploitation with scope change because executing another tenant's flow can reach data and integrations outside the attacker's authorization boundary. … Full risk analysis with EPSS, KEV, and SSVC signal comparison available after sign-in.
Exploit Scenario An attacker who has registered a low-privilege account or obtained any valid API key on a shared Langflow instance learns a victim flow UUID (from a screenshot, support ticket, shared link, or the pre-patch 403-vs-404 oracle on /api/v1/run*) and POSTs it as the 'model' field to /api/v1/responses with their own API key, as shown in the published PoC. The server executes the victim's flow under the victim's configuration, returning its output and consuming the victim's quota and any integrations (vector stores, LLM provider keys, internal APIs) wired into that flow. …
Remediation Vendor-released patch: upgrade to Langflow 1.9.1 or later (pip install --upgrade 'langflow>=1.9.1'), which applies the fix from PR #12832 (https://github.com/langflow-ai/langflow/pull/12832) by normalizing user_id once and enforcing ownership on both the UUID and endpoint_name lookup branches, returning 404 on cross-user lookups to avoid an existence oracle, and routing /api/v1/run* through auth-aware wrappers (get_flow_for_api_key_user, get_flow_for_current_user). … Detailed patch versions, workarounds, and compensating controls in full report.

Recommended ActionAI

Within 24 hours: Identify all Langflow deployments and determine their current versions. …

Sign in for detailed remediation steps and compensating controls.

Threat intelligence, references, and detailed analysis are available after sign-in.

Share

CVE-2026-55255 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy