CVE-2026-105698

CVE-2026-105698 is a medium-severity missing authorization vulnerability in langflow (pip), affecting versions >= 1.0.0, < 1.10.1. It is fixed in 1.10.1, 0.10.1.

Does this CVE actually affect you?

Kodem shows which CVEs are reachable and running in your applications, so you fix what's exploitable, not just what's listed.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Runtime intelligence, not another scanner.

Summary

Langflow : Cross-user flow access and vertex execution via deprecated /api/v1/build/{flow_id}/vertices endpoints

Before Langflow 1.10.1, two deprecated but still-routed endpoints in the chat API did not check that the authenticated caller owns the flow referenced in the URL path:

  • POST /api/v1/build/{flow_id}/vertices (retrieve_vertices_order)
  • POST /api/v1/build/{flow_id}/vertices/{vertex_id} (build_vertex)

Any authenticated user who knows (or obtains) another user's flow_id could load that user's private flow graph, enumerate its vertex IDs, and build (execute) individual vertices of it, receiving the vertex results in the response.

Both routes are declared with deprecated=True, include_in_schema=False, so they do not appear in the OpenAPI docs, but they remained registered on the router. The Langflow UI no longer calls them (it uses POST /api/v1/build/{flow_id}/flow), so they are only reachable by direct HTTP requests.

The issue is fixed in Langflow 1.10.1 (langflow-base 0.10.1) by #13153.

Details

In affected versions, both handlers go straight to the graph loader:

  • retrieve_vertices_order (src/backend/base/langflow/api/v1/chat.py, lines 81-159 in 1.9.1) only required authentication via dependencies=[Depends(get_current_active_user)]. The user was never injected into the handler, and the flow was loaded with build_graph_from_db(flow_id=flow_id, ...).
  • build_vertex (chat.py, lines 320-491 in 1.9.1) receives current_user, but only uses it for variable resolution (user_id=str(current_user.id)). It is never used to scope the flow lookup. The graph is taken from the chat-service cache keyed by flow_id, or rebuilt with build_graph_from_db on a cache miss.
  • build_graph_from_db_no_cache (src/backend/base/langflow/api/utils/flow_utils.py) does a bare primary-key lookup, session.get(Flow, flow_id), with no owner filter.

The supported replacement, POST /api/v1/build/{flow_id}/flow, already restricted the lookup to the owner or a PUBLIC flow (added in #12305 for GHSA-qj98-rhf8-v93f). The deprecated siblings were not covered by that fix, nor by the _read_flow fix for GHSA-8c4j-f57c-35cf.

Additional side effects in affected versions:

  • retrieve_vertices_order stores the graph in the chat-service cache under the victim's flow_id (chat_service.set_cache(str(flow_id), graph)). When the request includes a data body, the cached graph is attacker-supplied.
  • build_vertex schedules log_vertex_build for the victim's flow_id, so attacker-triggered builds are recorded in the victim flow's vertex build history.

Note on older versions: up to and including 1.7.1, these two routes had no authentication dependency at all. Authentication was added in 1.7.2 by #10977, but no ownership check was added. This advisory covers the missing ownership check, which is present in every release from 1.0.0 (when the routes were introduced) through 1.10.0.

Attack scenario

  1. The attacker authenticates as any valid user.
  2. The attacker obtains a victim flow_id (shared URLs, exported flow files, logs, screenshots, etc.).
  3. POST /api/v1/build/{victim_flow_id}/vertices returns 200 OK with {"ids": [...], "run_id": "...", "vertices_to_run": [...]} listing the victim flow's vertex IDs (component type plus suffix, e.g. ChatInput-abc12).
  4. The attacker calls POST /api/v1/build/{victim_flow_id}/vertices/{vertex_id} for a returned ID. The victim's graph is loaded and the vertex is built. Its results, outputs and artifacts are returned to the attacker.

Proof of concept

Observed on langflow==1.9.1 using the project's test client and in-memory SQLite fixtures (see the attached poc.zip):

Request Expected (hardened) Observed on 1.9.1
Attacker → POST /api/v1/build/{victim_flow_id}/vertices 404 Not Found 200 OK with vertex order payload
Attacker → POST /api/v1/build/{victim_flow_id}/vertices/<bogus-id> 404 Not Found 500 {"detail":"Vertex <id> not found"}: the victim graph was loaded before the vertex lookup failed
Owner (control) → same endpoints non-404 non-404

On 1.10.1 and later, the attacker requests return 404 Not Found. This is covered by regression tests in src/backend/tests/unit/test_endpoints.py:

  • test_get_vertices_returns_404_for_other_users_private_flow
  • test_get_vertices_with_supplied_data_returns_404_for_other_users_private_flow
  • test_build_vertex_returns_404_for_other_users_private_flow

Workarounds

If upgrading is not immediately possible, block POST /api/v1/build/*/vertices and POST /api/v1/build/*/vertices/* (and GET /api/v1/build/*/*/stream) at a reverse proxy. The Langflow UI does not use these routes.

Impact

  • Confidentiality (Low): Discloses the structure of private flows (vertex IDs and component types) and the outputs of vertices the attacker chooses to build. That includes values hardcoded in node configuration, such as prompt text or fixed inputs.
    • Global variables and credentials in the variable store are not exposed, because variable resolution uses the caller's user_id.
    • The victim's stored flow definition is not returned wholesale.
  • Integrity (Low): The attacker can trigger execution of the victim's nodes, including any side effects baked into their configuration (fixed endpoints, webhooks, hardcoded API keys). Build records are written under the victim's flow_id. The attacker cannot modify the stored flow.
  • Availability: None.

The attacker must be authenticated and must know the target flow UUID. Flow UUIDs are random v4 values, so blind enumeration is not practical.

The application does not perform an authorization check before performing a sensitive operation. Typical impact: unauthorized access to restricted functionality or data.

CVE-2026-105698 has a CVSS score of 5.4 (Medium). The vector is network-reachable, low privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (1.10.1, 0.10.1); upgrading removes the vulnerable code path.

Affected versions

langflow (>= 1.0.0, < 1.10.1) langflow-base (< 0.10.1)

Security releases

langflow → 1.10.1 (pip) langflow-base → 0.10.1 (pip)

Kodem intelligence

Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.

Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.

Already deployed Kodem?

See it in your environmentNew to Kodem? Get a demo →

Remediation advice

Fixed in Langflow 1.10.1 (langflow-base 0.10.1) by #13153 (merge commit fb3d6ec90b). Both handlers now:

  1. inject current_user (for retrieve_vertices_order, this replaces the dependencies-only declaration),
  2. load the flow with an owner-scoped query and return 404 when it is not found, so a flow you don't own looks the same as a missing flow, and
  3. call ensure_flow_permission(current_user, FlowAction.EXECUTE, ...) before building or caching any graph.
# retrieve_vertices_order / build_vertex (1.10.1)
stmt = (
    select(Flow)
    .where(Flow.id == flow_id)
    .where((Flow.user_id == current_user.id) | (Flow.access_type == AccessTypeEnum.PUBLIC))
)
flow = (await session.exec(stmt)).first()
if not flow:
    raise HTTPException(status_code=404, detail=f"Flow with id {flow_id} not found")
await ensure_flow_permission(
    current_user,
    FlowAction.EXECUTE,
    flow_id=flow_id,
    flow_user_id=flow.user_id,
    workspace_id=flow.workspace_id,
    folder_id=flow.folder_id,
)

Related hardening in later releases:

  • #14342 (1.11.2) applies the same guard to the sibling GET /api/v1/build/{flow_id}/{vertex_id}/stream route.
  • #14497 (1.12.0) makes all three deprecated vertex routes owner-only, dropping the PUBLIC exception, because their graph cache is keyed by flow UUID rather than by the executing user.

Users should upgrade to 1.10.1 or later. The latest release is recommended.

Frequently Asked Questions

  1. What is CVE-2026-105698? CVE-2026-105698 is a medium-severity missing authorization vulnerability in langflow (pip), affecting versions >= 1.0.0, < 1.10.1. It is fixed in 1.10.1, 0.10.1. The application does not perform an authorization check before performing a sensitive operation.
  2. How severe is CVE-2026-105698? CVE-2026-105698 has a CVSS score of 5.4 (Medium). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
  3. Which packages are affected by CVE-2026-105698?
    • langflow (pip) (versions >= 1.0.0, < 1.10.1)
    • langflow-base (pip) (versions < 0.10.1)
  4. Is there a fix for CVE-2026-105698? Yes. CVE-2026-105698 is fixed in 1.10.1, 0.10.1. Upgrade to this version or later.
  5. Is CVE-2026-105698 exploitable, and should I be worried? Whether CVE-2026-105698 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
  6. What actually determines whether CVE-2026-105698 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
  7. How do I fix CVE-2026-105698?
    • Upgrade langflow to 1.10.1 or later
    • Upgrade langflow-base to 0.10.1 or later

Other vulnerabilities in langflow

Stop the waste.
Protect your environment with Kodem.