On September 1, VulnCheck told SecurityWeek that attackers had started using CVE-2026-0768 against Langflow in the wild. BleepingComputer’s write-up the same day is the version most Python teams will see: unauthenticated code execution, root on the box, then a shopping list of environment variables. OPENAI_API keys. AWS access and secret keys. LANGFLOW_SUPERUSER. A secret_key file under /root/.cache/langflow. A peek at .ssh and the size of bash history.
Langflow is a Python low-code UI for wiring agents, RAG graphs, and chatbots. People like it because they can drag boxes instead of writing FastAPI. Attackers like it because those boxes often sit on a public port with the same process that holds production credentials.
This is not a Langflow-only story. It is what happens when a Python app treats a user-supplied string as something to execute, then runs that process as root, then stores cloud keys in the environment because “that’s how tutorials do it.” We have written the generic version of this. This week just gave it a CVE number and a honeypot count.
What actually shipped this week
CVE-2026-0768 is a 9.8. Trend Micro’s Zero Day Initiative reported it in July 2025. It became public as a zero-day in January 2026. Every Langflow release through 1.4.2 is listed as affected. The NVD description is blunt: a code parameter on a validate endpoint is not validated before it is used to execute Python.
SOCRadar’s September 1 note is useful for the part vendors hate to say out loud. Public records name 1.4.2. They do not give a clean, confirmed fixed version that you can screenshot into a ticket. If you run Langflow, you compare your build against current vendor guidance and you take it off the open internet until that comparison is done. “We’ll patch on Friday” is not a plan when the exploit does not need a login.
SOCRadar also pairs this with a Rails bug the same week. The two flaws are not a single campaign. The overlap is operational: both sit in application-layer components that hold powerful credentials. Patching the service is step one. Assuming the credentials are still secret is how you stay owned after the patch.
VulnCheck’s Caitlin Condon said there is no known public proof-of-concept. That did not slow anyone down. UK honeypots saw at least 50 attempts over the weekend, then about 360 by Monday, mostly from Russian-origin traffic. The payloads were reconnaissance: env vars, secret files, SSH, history. Credential harvesting, not a clever new implant family.
Langflow has had a year of this. Before 2026, VulnCheck counted one Langflow bug known to be exploited in the wild. In 2026 they have seen 11 more. Separate from 0768, they counted more than 15,000 successful attacks against instances vulnerable to CVE-2026-0769, CVE-2025-3248, and CVE-2026-5027. In March, CVE-2026-33017 was used within about a day of disclosure to run Python and grab .env and database files. Later CVEs covered arbitrary file writes, auth bypass into other users’ workflows, and more root command execution.
If your mental model is “we will patch when CISA puts it on a list,” you are behind the people already grepping your environment.
The three stacked mistakes
The validate endpoint is the headline. The stacked mistakes are why a code-injection bug turns into stolen AWS keys.
The process runs as root. Condon’s notes keep mentioning /root/.cache and root privileges. A code-execution bug in a user-owned service is bad. A code-execution bug in a service that is already root is a full box. There is no Python reason for a flowchart UI to be root. There is a Docker-compose reason: the first compose file used user: root or no user at all, and nobody changed it.
Secrets live in the same process environment. OPENAI_API_KEY in env is convenient. It is also the first thing a one-line os.environ dump returns. Same for AWS_ACCESS_KEY_ID. If the agent needs a model, give it a short-lived scoped token from a sidecar or an instance role, not a long-lived key that can also delete S3 buckets. If you have already put those keys on an exposed Langflow, rotate them. Do not “monitor for now.”
The “validator” executes. Calling an endpoint /validate does not make exec safer. If the handler’s job is “run this string as Python and tell me if it parses,” you built an anonymous interpreter and put it on the network. RestrictedPython, sandbox modules, and “we only eval in a try/except” have a long record of losing to the language they are trying to contain. Untrusted Python is not a validation problem. It is a process-isolation problem, and most low-code tools do not pay for that isolation.
The supply-chain piece is the cousin of this. Pip packages are one way untrusted code arrives. A browser-reachable editor is another. Both end with your interpreter running someone else’s text.
What to do this week if Langflow is on your network
No exploit walkthrough. You do not need one.
- Find every Langflow process. Compose files, Kubernetes deployments, that one GPU box a researcher forwarded on port 7860.
- If it is reachable from the internet, pull it. VPN or SSO in front, or it stays off. SOCRadar’s line is the right one: restrict untrusted networks until remediation is confirmed.
- Check the version. 1.4.2 and earlier are in the affected set. If you cannot prove you are past the vendor’s current fix, assume you are not.
- Assume credentials on that host are burned. Rotate OpenAI, AWS, Langflow superuser, anything in
.env, anything in the process environment. Rotate the Langflow secret_key. Rotate SSH keys if that box had them. - Stop running it as root. A dedicated user with no sudo and no access to the rest of the company’s disk is the minimum. Root was never required to draw a flowchart.
- Stop storing cloud keys in the Langflow container. If the graph must call OpenAI, use a proxy that injects a key the graph cannot print.
If you never installed Langflow, you are not done. Search for the same pattern in internal tools: Streamlit apps that exec a text box, JupyterHub on a public IP, agent playgrounds that run model-generated code, MCP servers that expose a shell. We have a production agents article that is optimistic about tools. Optimism still requires a boundary between the model and exec.
Jupyter is the honest version of this product. It is an interpreter in a browser, and people who run it in production put it behind tokens, spawned kernels, and network policies because they remember what happens when they do not. Langflow looks less dangerous because it has a graph UI. The graph UI still has a code editor. The code editor still talks to CPython. If that CPython can read AWS keys, the graph was never the security boundary.
The rest of 2026’s Langflow list is the same pattern with different doors. CVE-2026-5027 was used to write files. CVE-2026-55255 was used to reach other users’ workflows. CVE-2026-0770 was used for root commands and another pass at cloud credentials and container metadata. You do not need the full catalog memorized. You need one rule: a Python process that accepts code from a socket is an interpreter, and interpreters do not belong on 0.0.0.0 with production env vars.
What to do in your own code
If you are building a product that accepts Python from a browser, the safe default is to refuse.
import ast
def accept_only_parseable_source(src: str) -> ast.AST:
"""Parse. Do not execute. Parsing is not a sandbox."""
if len(src) > 50_000:
raise ValueError("source too large")
return ast.parse(src, mode="exec")
ast.parse tells you whether the text is syntactically valid. It does not run it. That is the entire point of a validate endpoint that is actually a validator.
If you must run user code, do it in a throwaway process with no secrets, no network, a hard timeout, and a user that cannot read /home. Do not do it in the API worker that also holds os.environ["AWS_SECRET_ACCESS_KEY"]. Do not do it as root because Docker made that the default.
For configuration, stop copying .env files into images that listen on 0.0.0.0. pydantic-settings and a secrets manager are boring. Boring is what you want when the alternative is a honeypot logging your OpenAI key.
None of this required a new Python version. 3.14 will not save a validate endpoint.
Docker defaults make this worse than a bad code review. A compose file with no user: key, a published port, and env_file: .env is a complete steal-me kit. People copy that file from a README because the demo has to work on a laptop in five minutes. The demo never included “and then we put it on a public IP next to billing.” If you cannot name the Linux user the container runs as, it is root. If you cannot name which network can reach port 7860, it is the internet.
Rotation is not a Slack message. It is new OpenAI keys, old keys deleted, AWS access keys deactivated, instance profiles checked for surprise access keys created this week, Langflow admin passwords changed, and a grep of CI logs for the old values. If the box had SSH keys, those too. Then look at CloudTrail or OpenAI usage for the days before you noticed.
Why agent UIs keep repeating this
Low-code AI tools collapse three jobs into one process: the editor, the runtime, and the secret store. That is convenient in a demo. It is how you get a year with a dozen exploited CVEs.
The market will keep shipping these UIs because they sell. Your job is to treat them like CI runners that compile untrusted code, not like Notion. Put them on a private network. Give them a role that can call one model and nothing else. Patch them like you patch browsers. When VulnCheck says exploitation has started, believe the first report.
If you need a checklist that is not Langflow-specific, the older Python security practices piece still holds: least privilege, no long-lived keys in env of networked apps, no eval/exec on user input, dependency pinning, and an actual patch cadence. This week is that list with a product name attached.
Rotate the keys. Take the port off the internet. Then decide whether you still need a web form that runs Python. Most teams will find they needed a private notebook and a secrets manager, not another public interpreter.
Discussion
Leave a comment
No comments yet
Be the first to start the conversation.