1. CVE-2026-33017
A vulnerability in Langflow allows unauthenticated remote code execution (RCE).
It stems from a feature that lets users run a shared flow without logging in. The endpoint accepts attacker-supplied flow data without validation and executes the code contained within it — meaning an attacker can execute arbitrary code on the server with no authentication at all.
Langflow is an open-source tool for visually building AI workflows by connecting blocks such as chat input, model calls, document retrieval, API requests, and output display.
This vulnerability affects Langflow deployments that expose flows publicly. Running a public flow requires no authentication, so an attacker only needs the target flow's identifier to execute arbitrary code on the server — potentially leading to full system compromise.
| Item | Details |
|---|---|
| CVE ID | CVE-2026-33017 |
| Affected Product | Langflow (open-source AI workflow/agent builder, 140k+ GitHub stars) |
| Vulnerability Type | CWE-306 (Missing Authentication for Critical Function) + CWE-94 (Code Injection) |
| CVSS | 9.8 (Critical) under v3.1; GitHub's own v4 score is 9.3 |
| Impact | Unauthenticated arbitrary Python code execution (full system compromise) |
| Affected Versions | All versions prior to 1.9.0 |
| Patched Version | 1.9.0 |
2. The Vulnerable Feature: "Public Flow"
Langflow has a public flow feature that lets others run a workflow without logging in — designed for exposing demos or chatbots externally. By itself, this is a legitimate design.
The endpoint behind it:
POST /api/v1/build_public_tmp/{flow_id}/flow
This endpoint is intentionally unauthenticated. The problem is that the request also accepted an optional data parameter.
3. The Real Problem: Untrusted Input on a Trusted Path
Correctly, running a public flow should only load and execute the flow definition stored in the database. A caller should be able to say "run this flow," but not dictate the flow's actual contents.
Instead, when a data parameter was present in the request, the endpoint used the value from the request body instead of the value from the database. A request meaning "run this flow_id" could effectively become "run this flow_id, but replace what actually executes with the data I'm sending now."
Langflow's flow data is organized into nodes (components), and each node can embed a Python code snippet via the custom component feature. This let an attacker smuggle a node containing arbitrary Python code inside the data parameter.
4. Tracing the Code Path
-
build_public_tmp()— the endpoint handler; no auth check, acceptsdataas-is. -
create_graph()— should enforce "public flows are read from the DB only," but ifdatais present, it builds the graph from attacker-supplied data instead. -
eval_custom_component_code()— extracts and evaluates each node's Python code, treating the attacker's injected snippet as legitimate node code. -
prepare_global_scope()→exec()— the extracted code is passed directly toexec(). No sandboxing, no input validation, no whitelist. Code enteringexec()runs with the same privileges as the server process.
The core issue isn't a single buggy function — it's a broken trust boundary. build_public_tmp → create_graph was supposed to assume "this request is unauthenticated, so trust the DB value only," and the data parameter broke that assumption. eval_custom_component_code and exec() were designed to process already-trusted flow data, so neither had independent validation logic.
Accordingly, the GitHub security advisory's fix didn't try to sandbox exec() — it removed the data parameter from the endpoint entirely and forced public flows through the build_graph_from_db() path only. The fix prevents dangerous code from ever entering the execution path, rather than trying to block it once it's already there.
5. Attack Requirements
- At least one public flow must exist on the target instance (common for demo/chatbot deployments)
- Or, if the default
AUTO_LOGIN=trueis enabled, an attacker could create a public flow directly via the unauthenticated auto-login path - The public flow's UUID (typically exposed in the shared link, easy to obtain)
- No credentials required
6. Mitigation
- Upgrade to Langflow 1.9.0+ — the only verified fix. (Some reports claimed an intermediate 1.8.x patch, but reproductions showed it remained exploitable.)
- If immediate upgrade isn't feasible:
- Disable the public flow feature, or avoid it unless necessary
- Review the
AUTO_LOGINdefault and disable it if not required - Don't expose the Langflow API directly to the internet — put it behind an authenticating proxy or firewall
- Add a WAF/proxy rule to detect and block requests to
build_public_tmpthat include adataparameter


Top comments (0)