A critical, unauthenticated remote code execution flaw in Langflow — tracked as CVE-2026-33017 and rated CVSS 9.3 (Critical) — lets attackers run arbitrary Python on the host through an exposed, unauthenticated API endpoint. It affects Langflow 1.8.13 and earlier, was disclosed on March 18, 2026, and is fixed in Langflow 1.8.1. With a working proof-of-concept already public and CISA having added the bug to its Known Exploited Vulnerabilities catalog, any internet- or network-reachable Langflow deployment should be treated as an emergency patch.
Why this matters
Langflow is a widely adopted open-source, low-code platform for assembling LLM-powered applications and AI agent workflows. Developers use its visual canvas to wire together complex AI pipelines, and the platform leans heavily on an API-driven backend. That same flexibility expands the attack surface: Langflow servers are routinely placed on internal networks or directly on the public internet, so a critical RCE in its API translates into outsized real-world risk.
Root cause: unsanitized input reaching exec()
The bug lives in the POST /api/v1/build_public_tmp/{flow_id}/flow endpoint, which exists to let public flows be built without authentication. Two design problems combine into a critical flaw:
- No authentication. The endpoint serves any caller, authenticated or not.
- Attacker input handed to
exec(). The handler takes an optionaldataparameter. Rather than relying solely on the flow definition already stored in the database, the server uses the caller-supplieddatavalue when it is present.
That attacker-controlled flow data — with malicious Python tucked inside node template definitions — flows through Langflow's graph-building pipeline and lands in the prepare_global_scope() function, where it is compiled and run through Python's exec() with no sandboxing.
The dangerous pattern sits in src/lfx/src/lfx/custom/validate.py:
exec(compiled_code, exec_globals)
Here compiled_code is built from attacker-supplied AST nodes with no isolation. Because exec() evaluates every top-level AST node — including Assign nodes — a statement like:
_x = os.system("id")
executes the moment the graph is constructed, before any later validation could plausibly intervene. The outcome is full, unsandboxed execution under the privileges of the Langflow process.
Preconditions an attacker needs
Two conditions are required, and both are satisfied trivially on a stock deployment:
- A valid public Flow ID. The target must have at least one public flow.
AUTO_LOGIN=true(the default). Langflow ships with auto-login enabled. That lets an unauthenticated actor pull a superuser token from/api/v1/auto_loginand then create a public flow, minting a valid Flow ID without ever supplying credentials.
In other words, on a freshly installed, default-configured Langflow instance that's reachable over the network, an attacker needs zero credentials to reach full RCE.
Walk-through of the exploit
The attack chains three steps:
Step 1 — Grab a superuser token. Send a GET to /api/v1/auto_login to receive an access token. With AUTO_LOGIN=true, no credentials are needed.
Step 2 — Create a public flow. Use that token to POST a new flow with "access_type": "PUBLIC" to /api/v1/flows/, then keep the returned Flow ID.
Step 3 — Fire the payload. Send crafted JSON to the unauthenticated /api/v1/build_public_tmp/{flow_id}/flow endpoint. The payload buries a malicious Python command inside the code value of a node template definition within the data parameter.
A representative code value such as:
import os; os.system("touch /tmp/pwned")
runs immediately on the server during graph building. The command is arbitrary — it can fetch and launch a reverse shell, plant persistence, or exfiltrate secrets just as easily.
Not the same as CVE-2025-3248
This is a separate issue from the earlier CVE-2025-3248, which abused the /api/v1/validate/code endpoint. Having patched CVE-2025-3248 does not protect you here — the vulnerable code path has moved to a different endpoint. The takeaway is to upgrade by version rather than assume an old fix still covers you.
Impact
Successful exploitation yields code execution with the Langflow process's full privileges, opening the door to:
- Complete server takeover and persistent backdoors
- Theft of data, API keys, and credentials stored on or reachable from the host
- Lateral movement into connected internal segments
- Deployment of cryptominers or ransomware
- Using the box as a pivot for follow-on attacks
Given the public PoC and the credential-free path on default setups, active in-the-wild exploitation should be considered likely and imminent — a view reinforced by CISA adding the flaw to its KEV catalog.
Remediation and mitigations
- Upgrade now. Move to Langflow 1.8.1 or later. The fix strips the attacker-controllable
dataparameter out of thebuild_public_tmpfunction inchat.py, removing the injection vector. - Turn off auto-login. Set
AUTO_LOGIN=falsein every production environment to eliminate the zero-credential precondition. - Restrict the endpoint. Block or limit access to
/api/v1/build_public_tmp/at the firewall or reverse proxy, especially from untrusted networks. - Audit public flows. Look for unexpected public flows that could signal prior recon or exploitation.
- Watch the logs. Hunt for unusual requests to
build_public_tmpand anomalous child processes spawned by the Langflow process.
Bottom line
CVE-2026-33017 checks every box of a worst-case vulnerability: no authentication, a public PoC, and total compromise on success. Langflow's default AUTO_LOGIN=true combined with an unguarded exec() over user input makes for a trivially exploitable, fully unauthenticated RCE. Patch as an emergency; if you can't upgrade immediately, disabling auto-login and fencing off the endpoint at the perimeter are essential stopgaps. As AI tooling spreads, its security hygiene has to keep up.
References: