CVE-2026-33017 is not just another critical RCE in an open-source Python web application. It is a clean example of what happens when an AI workflow platform exposes a public execution path, accepts caller-supplied workflow definitions, and lets that path reach unsandboxed Python execution.
The vulnerable product is Langflow, a visual platform for building and deploying AI-powered agents and workflows. The affected endpoint is POST /api/v1/build_public_tmp/{flow_id}/flow. According to NVD, Langflow versions prior to 1.9.0 allowed this public flow build endpoint to run without authentication. When the optional Veri parameter was supplied, the endpoint used attacker-controlled flow data containing arbitrary Python code in node definitions instead of the stored flow data from the database. That code was then passed to exec() without sandboxing, resulting in unauthenticated remote code execution. NVD assigns the issue a CVSS v3.1 score of 9.8 Critical, while GitHub’s CNA scoring lists CVSS v4.0 9.3 Critical. (NVD)
CISA added CVE-2026-33017 to the Known Exploited Vulnerabilities catalog on March 25, 2026, under the name “Langflow Code Injection Vulnerability,” with a required action deadline of April 8, 2026 for covered federal agencies. NVD’s record also shows CISA’s SSVC assessment marking exploitation as active, automatable as yes, and technical impact as total. (NVD)
That combination matters. This is a network-reachable bug. It requires no valid account. It requires no user interaction. It affects a tool that frequently holds model provider keys, database connection strings, vector database credentials, cloud tokens, workflow state, and application secrets. When exploited, the attacker is not merely compromising a demo canvas. They may be landing inside the control plane of an organization’s AI application stack.
What defenders need to know first
| Öğe | Practical meaning |
|---|---|
| Güvenlik Açığı | CVE-2026-33017 |
| Ürün | Langflow |
| Main vulnerable endpoint | POST /api/v1/build_public_tmp/{flow_id}/flow |
| Güvenlik açığı sınıfı | Unauthenticated remote code execution through code injection and eval-style execution |
| Weaknesses | CWE-94, CWE-95, CWE-306 |
| Etkilenen sürümler | Langflow versions before 1.9.0 |
| Fixed version | 1.9.0 or later |
| Public exploitation | Confirmed, added to CISA KEV |
| Why it is severe | Public endpoint, no authentication, low complexity, server-side Python execution, likely access to secrets |
| Main defensive action | Upgrade, isolate Langflow from the public internet, rotate secrets, review logs, verify runtime behavior |
The clean remediation target is Langflow 1.9.0 or later. GitLab’s advisory database lists all versions before 1.9.0 as affected and 1.9.0 as fixed, and its solution is direct: upgrade to version 1.9.0 or above. PyPI shows langflow 1.9.0 was released on April 14, 2026, with newer versions available afterward, including 1.10.x by June 2026. (GitLab Danışma Veritabanı)
There was a short but important period of confusion around whether 1.8.2 was fixed. JFrog Security Research reported on March 26, 2026 that public sources gave the impression 1.8.2 was patched, but their testing found 1.8.2 still exploitable in both PyPI and Docker environments. They concluded that 1.9.0 was the correct patched version, and a GitHub issue opened the same day documented the mismatch between release notes and observed exploitability. (JFrog Security Research)
The lesson is simple: do not rely only on a release note when a critical vulnerability is already being exploited. Confirm the installed package, confirm the container image, confirm the patch behavior, and confirm that no exposed instance remained reachable during the vulnerable window.
The short technical version

The vulnerable endpoint existed to support public flows. Public flows are meant to be reachable without a logged-in user. That design goal is not automatically wrong. The problem was what the public endpoint accepted and what Langflow did with it.
A safe public flow build path should load a known flow definition from trusted server-side storage. It may accept inputs to that flow, but it should not let an anonymous caller replace the flow definition itself. CVE-2026-33017 broke that boundary. When a caller supplied the optional Veri parameter, Langflow could use that attacker-supplied flow data instead of the flow stored in the database. If the supplied flow data contained a node definition with Python code, that code could reach Langflow’s dynamic execution path.
GitHub’s advisory describes the core bug in direct terms: the public flow build endpoint allowed building public flows without requiring authentication; when Veri was supplied, attacker-controlled flow data containing arbitrary Python code in node definitions was used instead of stored database flow data; the code was passed to exec() with zero sandboxing. (GitHub)
Three mistakes combined into one high-impact failure:
| Boundary | What should have happened | What went wrong |
|---|---|---|
| Authentication boundary | Public flow access should expose only safe public functionality | The endpoint was intentionally unauthenticated, so every downstream control had to be stronger |
| Data authority boundary | Public execution should use server-stored flow definitions | Caller-supplied Veri could override the trusted flow definition |
| Execution boundary | User-influenced code should never reach raw unsandboxed execution | Attacker-controlled Python could reach exec() |
| Secret boundary | Workflow runtime should not expose broad credentials | Compromised Langflow processes often have access to .env, API keys, database strings, and cloud tokens |
| Network boundary | AI builder tools should not sit directly on the public internet | Many instances were reachable enough for mass scanning and exploitation |
That is why the vulnerability is more serious than a normal “missing auth” bug. The public endpoint existed for a feature. The security failure was allowing public callers to influence code-bearing flow structure and then executing it inside the Langflow service context.
Why this bug is different from a normal web RCE
A traditional RCE in a small web service may give the attacker a low-privilege shell inside one application container. That is still serious. CVE-2026-33017 often lands in a more sensitive place because Langflow is not just a web app. It is an AI workflow builder.
Langflow workflows may connect to LLM providers, vector stores, databases, file loaders, APIs, and internal tools. PyPI’s Langflow project description says the platform provides a visual authoring experience, built-in API and MCP servers, support for major LLMs and vector databases, multi-agent orchestration, and the ability to deploy workflows as APIs or MCP servers. (PyPI)
That integration density changes the blast radius. A compromised Langflow instance can expose:
| Asset type | Why it matters after RCE |
|---|---|
| Model provider keys | Attackers can run unauthorized inference, steal spend, or access model-connected workflows |
| Database connection strings | A workflow server may have direct access to application data or RAG stores |
| Vector database credentials | Embeddings, internal documents, and retrieval indexes may be reachable |
| Cloud tokens | A container or VM role may allow lateral movement into cloud services |
.env dosyalar | They often contain multiple secrets in one place |
| Flow definitions | Attackers can learn how the organization’s AI pipeline is wired |
| MCP or API tool credentials | Tool servers can become action channels, not just data sources |
| Reports and logs | Prior prompts, outputs, and user data may expose internal context |
This is why defenders should not treat CVE-2026-33017 as a standalone package upgrade. Upgrading is mandatory, but it is only the first step. Any exposed vulnerable instance should be handled as a potential credential compromise.
The root cause, public execution crossed into trusted code
The most useful way to understand the bug is as an execution-boundary failure.
The endpoint was public. That meant the system could not rely on user identity as the first line of defense. Public access should have narrowed what the caller could do. Instead, the public path accepted attacker-controlled Veri. That Veri could carry a flow graph. That graph could carry Python code. That Python code could be evaluated server-side.
In a workflow builder, “data” is often not inert. It may represent a graph of components, tools, configuration, templates, code fields, input bindings, and execution order. Treating that graph as ordinary request data is dangerous when parts of the graph are executable.
The GitHub advisory classifies the issue under three weaknesses: CWE-94 for improper control of code generation, CWE-95 for eval injection, and CWE-306 for missing authentication for a critical function. (GitHub) Those are not three unrelated labels. They describe the chain:
- The attacker influences code-bearing structure.
- The structure reaches dynamic evaluation.
- The reachable endpoint does not require authentication.
A safer design would have split flow execution into at least three layers:
| Katman | Safer design |
|---|---|
| Public request layer | Accept only non-code inputs required to run a specific public flow |
| Flow authority layer | Load flow structure from trusted server-side storage only |
| Execution layer | Run custom code in a constrained sandbox with explicit permissions |
| Secret layer | Do not expose broad process-level secrets to flow execution |
| Audit layer | Log who or what triggered each build, which stored flow was used, and what execution capabilities were invoked |
The patch direction confirms this reading.
What the patch changed
The key Langflow commit referenced by NVD is 73b6612, titled “fix: prevent RCE via data parameter in build_public_tmp endpoint.” The diff removes the Veri parameter from build_public_tmp, adds a security note that the Veri parameter is not accepted for public flows, states that public flows must execute the stored flow definition only, and passes data=None when calling start_flow_build. It also adds tests verifying that attempted custom flow data is ignored and that the endpoint works without the Veri parameter. (GitHub)
The patch is important because it does not merely add authentication to the public endpoint. For this particular feature, adding authentication would not fully match the intended product behavior. The public flow endpoint was supposed to be reachable. The safer fix was to prevent anonymous callers from replacing the flow definition.
| Vulnerable behavior | Safer patched behavior |
|---|---|
Public endpoint accepts Veri | |
| Public caller can influence flow definition | |
| Flow data may contain code-bearing nodes | |
| Code can reach server-side execution | |
| Stored flow definition can be bypassed | |
Public endpoint ignores caller-supplied Veri | |
| Flow definition must be loaded from the database | |
| Caller supplies inputs, not executable graph structure | |
Tests check that malicious Veri is ignored | |
| Public behavior remains, but authority over the flow definition is restored |
This distinction matters for other AI workflow platforms. If a public execution feature is required, the input contract must be narrow. Public callers can be allowed to provide values. They should not be allowed to provide executable structure.
Affected versions and current patch status
The safest operational interpretation is:
| Version state | Risk posture |
|---|---|
| Earlier than 1.9.0 | Treat as affected |
| 1.8.2 | Do not treat as fixed based on early release-note language |
| 1.9.0 | First fixed version documented by NVD, GitLab advisory, and patch references |
| Later 1.9.x or 1.10.x | Prefer current maintained release, after testing compatibility |
| Unknown container tag | Treat as suspicious until package version is confirmed inside the container |
latest Docker tag pulled during March 2026 | Verify manually, because tag timing may not match security expectations |
JFrog’s March 26 report is worth reading because it captures an operational trap: multiple sources appeared to imply that 1.8.2 was patched, but empirical testing showed it was still exploitable. Their recommendation at that time was to use langflow-nightly because the official patched version had not yet been released. As of the current PyPI record, 1.9.0 was later published on April 14, 2026, and newer versions are available. (JFrog Security Research)
For defenders reading this after April 2026, the answer is not “install the nightly.” The answer is to upgrade to a supported stable release at or above 1.9.0, preferably a current 1.10.x or later release after regression testing, and then confirm the vulnerable endpoint no longer accepts external flow definition data.
Use package inspection, not assumptions:
python -m pip show langflow langflow-base 2>/dev/null | sed -n '1,80p'
python - <<'PY'
import importlib.metadata as md
for package in ("langflow", "langflow-base"):
try:
print(f"{package}={md.version(package)}")
except md.PackageNotFoundError:
print(f"{package}=not installed")
PY
For containers, check the running image and then inspect the package inside the container:
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}' | grep -i langflow || true
docker exec <container_name> python -m pip show langflow langflow-base 2>/dev/null | sed -n '1,80p'
For Kubernetes, start with exposed services and images:
kubectl get pods,svc,ingress -A | grep -i langflow || true
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .spec.containers[*]}{.image}{" "}{end}{"\n"}{end}' \
| grep -i langflow || true
Those commands do not prove exploitability. They establish inventory. Inventory is the first step because many Langflow deployments live outside the standard production application list: in research environments, data science sandboxes, internal AI labs, demo VMs, notebooks promoted into services, or temporary cloud instances that become permanent.
How attackers moved from disclosure to exploitation
Sysdig’s threat research is one of the most useful public observations for this CVE because it describes the exploitation timeline, not just the vulnerability. Sysdig reported that the advisory was published on March 17, 2026 at 20:05 UTC and the first exploitation attempt they observed occurred on March 18 at 16:04 UTC, about 20 hours later. They also noted that no public GitHub PoC existed at the time of the first observed attack, which means attackers built working exploits from the advisory details themselves. (Sysdig)
That timeline should change how teams handle critical AI infrastructure advisories. Waiting for a public exploit repository is too slow. For CVE-2026-33017, the endpoint path and vulnerable mechanism were enough.
Sysdig observed several phases:
| Aşama | Observed behavior | Defender takeaway |
|---|---|---|
| Initial scanning | Requests resembling private nuclei-style templates and OAST callbacks | Mass validation can begin within hours |
| Custom exploit scripts | Python requests clients performing reconnaissance | Operators quickly move beyond “is it vulnerable” |
| Credential harvesting | Environment dumps, .env discovery, database file searches | Treat exposed instances as secret compromise |
| Stage-2 delivery | Attempts to download and run shell payloads | Network egress detection is critical |
| Shared infrastructure | Multiple sources exfiltrating to common C2 | Source IP alone is a weak indicator |
Sysdig also reported that attackers read sensitive files, performed system fingerprinting, tried stage-2 delivery, and harvested environment variables and .env files. In a typical Langflow deployment, those environment variables may include model provider keys, database connection strings, cloud credentials, and application secrets. (Sysdig)
This is why “we patched” is not enough. If an instance was reachable while vulnerable, the response should include credential rotation and incident review.
The cryptominer campaign shows commodity adoption
By June 2026, Trend Micro had tracked a cryptocurrency-mining campaign exploiting CVE-2026-33017. Their analysis is useful because it shows the vulnerability had moved from early scanning and custom exploitation into commodity malware delivery. The campaign used the Langflow RCE as an initial access vector, then pulled down a shell script, fetched a miner binary, disabled host-level defenses, killed rival miners, planted persistence, and started beaconing to command-and-control infrastructure. (www.trendmicro.com)
Trend Micro described a payload sequence where the malware raised ulimit, killed processes associated with rival miners, disabled AppArmor, UFW, iptables, SELinux, the NMI watchdog, and Alibaba Cloud’s Aliyun agent, removed certain backdoor accounts from earlier miner campaigns, planted cron and watchdog persistence, and began JSON heartbeat traffic. (www.trendmicro.com)
That behavior is not unique to AI tooling. It looks like standard Linux commodity compromise. That is the point. Attackers did not need a special AI-native payload. They used an AI workflow platform as a new front door into ordinary Linux infrastructure.
Trend Micro’s campaign also highlights why detection should not stop at the initial endpoint. After deployment, the malware shifted C2 traffic to standard HTTP on port 80 and used a Go net/http default user agent. The staging and C2 ports differed, so a rule that only watched the payload staging port would miss the infected host after deployment. (www.trendmicro.com)
The defensive lesson is that endpoint exploitation and post-exploitation behavior must both be monitored. A WAF rule for build_public_tmp is helpful, but it will not catch a miner that is already running.
The real risk is the AI pipeline blast radius
CVE-2026-33017 matters because Langflow sits at the intersection of application logic, model providers, workflow orchestration, secrets, and developer experimentation. Many organizations still do not classify AI workflow builders as production control planes. That is a mistake.
A Langflow instance may be owned by a machine learning team, deployed by a developer, reachable through a temporary reverse proxy, and connected to real credentials. It may not be covered by the same vulnerability management process as a customer-facing SaaS application. It may not have a documented owner. It may not be patched on the same schedule. It may not have egress restrictions. It may not be in the official CMDB. But attackers do not care which team owns it. They care whether it has an HTTP endpoint, secrets, and execution.
That makes the blast radius broader than the CVE description alone implies.
| Traditional RCE question | AI workflow RCE question |
|---|---|
| Can the attacker execute commands on the server | Can the attacker execute commands in a workflow runtime that holds AI and cloud credentials |
| Is the app publicly exposed | Are internal AI tools exposed through forgotten tunnels, demos, or shared links |
| What user does the process run as | What model keys, database strings, and tool permissions does that process hold |
| Was a web shell dropped | Were prompts, embeddings, flow definitions, secrets, or API tokens accessed |
| Was the host patched | Were connected services rotated, revoked, and reviewed |
| Did the attacker persist on the host | Did the attacker modify flows, tools, components, or credentials |
This is why security teams should handle exposed Langflow as both an application security incident and an AI infrastructure incident.
Safe validation without handing attackers a payload
A defensive validation workflow should answer five questions:
- Are we running Langflow.
- Which versions are installed.
- Was any instance internet-exposed.
- Was the vulnerable endpoint reached.
- Did post-exploitation behavior occur.
Do not start by firing public exploit code at production. Start with inventory and logs.
For host-level package inventory:
python - <<'PY'
import importlib.metadata as md
from packaging.version import Version, InvalidVersion
packages = ["langflow", "langflow-base"]
for package in packages:
try:
v = md.version(package)
except md.PackageNotFoundError:
continue
try:
status = "affected" if Version(v) < Version("1.9.0") else "not affected by version"
except InvalidVersion:
status = "unknown version format"
print(f"{package} {v} -> {status}")
PY
For file-system discovery on Linux hosts where Langflow may have been installed in virtual environments:
find / -path '*/site-packages/langflow*' -o -path '*/site-packages/langflow_base*' 2>/dev/null | head -50
For container-heavy environments:
docker ps --format '{{.ID}} {{.Image}} {{.Names}}' \
| awk 'tolower($0) ~ /langflow/ {print}'
docker images --format '{{.Repository}}:{{.Tag}} {{.ID}} {{.CreatedSince}}' \
| awk 'tolower($0) ~ /langflow/ {print}'
For Kubernetes exposure:
kubectl get ingress -A | grep -i langflow || true
kubectl get svc -A | grep -i langflow || true
kubectl get pods -A -o wide | grep -i langflow || true
For reverse proxy logs, search for the vulnerable route:
zgrep -h 'build_public_tmp' /var/log/nginx/access.log* 2>/dev/null \
| awk '{print $1, $4, $5, $6, $7, $9, $12}' \
| head -100
For common Langflow port exposure:
ss -lntp | awk '$4 ~ /:7860$/ || $4 ~ /:7861$/ {print}'
For cloud-hosted environments, combine service discovery with security group review. The dangerous state is not “Langflow exists.” The dangerous state is “Langflow exists, is reachable by untrusted networks, runs a vulnerable version, and holds useful credentials.”
What to look for in logs
Endpoint access alone is not proof of compromise. But for CVE-2026-33017, endpoint access is important enough to escalate. Look for:
| Sinyal | Neden önemli | False-positive notes |
|---|---|---|
POST /api/v1/build_public_tmp/ | Direct contact with the vulnerable endpoint | Legitimate public flow usage may exist |
| JSON body containing unexpected flow graph data | Suggests an attempt to override stored flow data | Body logging may not be enabled |
python-requests user agent | Seen in custom exploitation, but also common in legitimate scripts | Not sufficient alone |
client_id=nuclei-scanner | Sysdig observed this in early scanning traffic | Could be spoofed |
| OAST or interactsh domains | Often used for out-of-band exploit validation | Security teams may use them too |
kıvrıl veya wget spawned by Python | Common stage-2 delivery behavior | Some legitimate automation uses these |
Reads of .env, /etc/passwd, database files | Stronger post-exploitation signal | Context matters, but investigate immediately |
| Outbound HTTP to unusual VPS IPs | Potential C2 or exfiltration | Requires environment baseline |
| XMRig or mining pool ports | Cryptominer activity | Rarely legitimate on application servers |
Sysdig’s observed exploitation included OAST callbacks, python-requests, credential file reads, .env discovery, outbound exfiltration, and stage-2 payload delivery. Their runtime detection section emphasizes behavior-level detection because rules that detect shell execution, sensitive file reads, OAST DNS lookups, and outbound C2 can work even before a CVE-specific signature exists. (Sysdig)
A simple access-log triage command:
zgrep -hE 'POST .*build_public_tmp|build_public_tmp/.*/flow' /var/log/nginx/access.log* 2>/dev/null \
| tee /tmp/langflow-build-public-tmp-hits.txt
awk '{print $1}' /tmp/langflow-build-public-tmp-hits.txt | sort | uniq -c | sort -nr | head -30
A broader process-behavior triage on Linux:
ps auxww | egrep -i 'xmrig|procq|kdevtmpfsi|kinsing|monero|curl .*sh|wget .*sh|Go-http-client' | grep -v egrep || true
find /tmp /var/tmp -maxdepth 3 -type f -mtime -30 2>/dev/null \
| egrep -i 'xmrig|procq|ks\.tar|lambsys|\.systemd|\.X11-unix' || true
A suspicious outbound connection check:
ss -plant | egrep ':3333|:4444|:5555|:6666|:7777|:8080|:8443' || true
These commands are triage aids. They do not replace forensic collection. If you find evidence of exploitation, preserve logs, snapshot affected systems, rotate credentials, and involve incident response.
A Sigma-style detection idea for proxy logs
The following rule is intentionally defensive. It detects access to the vulnerable public flow build route. It does not include an exploit payload.
title: Langflow Public Flow Build Endpoint Access
id: 9e10edcc-33017-langflow-public-flow-build
status: experimental
description: Detects HTTP requests to the Langflow public flow build endpoint associated with CVE-2026-33017 exposure and exploitation attempts.
logsource:
category: webserver
detection:
selection_path:
cs-uri-stem|contains:
- "/api/v1/build_public_tmp/"
selection_method:
cs-method: "POST"
condition: selection_path and selection_method
fields:
- src_ip
- user_agent
- cs_method
- cs_uri_stem
- status
- bytes_out
- referer
falsepositives:
- Legitimate public Langflow flow execution in environments that intentionally expose public flows
- Internal security validation
level: high
If your log schema differs, map cs-uri-stem, cs-methodve user_agent to your SIEM fields. This rule should not be your only detection. Pair it with runtime rules for Python spawning shells, unusual file reads, and outbound callback traffic.
Reverse proxy hardening while upgrading
Network controls are not a replacement for patching. They are useful when you need to reduce exposure while packages, containers, and workflows are being updated.
A simple NGINX pattern is to require authentication before Langflow and block direct public access to the vulnerable route unless you have a documented need:
server {
listen 443 ssl;
server_name langflow.example.com;
auth_basic "Restricted Langflow";
auth_basic_user_file /etc/nginx/.htpasswd;
location ~* ^/api/v1/build_public_tmp/.*/flow$ {
allow 10.0.0.0/8;
allow 192.168.0.0/16;
deny all;
proxy_pass http://langflow_backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
proxy_pass http://langflow_backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
If public flow sharing is a business requirement, do not simply open the endpoint to the internet. Put it behind a design review. Confirm the version is fixed. Confirm public callers cannot submit flow definitions. Confirm logging captures request metadata. Confirm the runtime has minimal secrets. Confirm egress is restricted.
Incident response checklist for exposed instances
If an affected Langflow instance was reachable from the internet, take the incident path. Do not treat this as routine patching.
| Adım | Eylem | Neden |
|---|---|---|
| 1 | Remove public exposure or add authenticated reverse proxy immediately | Stops trivial continued exploitation |
| 2 | Upgrade to 1.9.0 or later | Fixes the vulnerable public flow behavior |
| 3 | Preserve access logs, application logs, container logs, and shell history | Needed for timeline and evidence |
| 4 | Search for build_public_tmp hits | Identifies possible exploitation attempts |
| 5 | Review process execution and network egress | Finds stage-2 payloads and exfiltration |
| 6 | Rotate model provider keys | Attackers commonly target environment variables |
| 7 | Rotate database and vector store credentials | Langflow often connects to data stores |
| 8 | Rotate cloud credentials and tokens | Host compromise may expose cloud access |
| 9 | Review flow definitions and custom components | Attackers may modify workflow behavior |
| 10 | Rebuild affected hosts or containers | Removes persistence and unknown changes |
| 11 | Add runtime detections | Catches future RCE-like behavior |
| 12 | Add Langflow to asset inventory and patch SLAs | Prevents recurrence |
Credential rotation is not optional if logs indicate endpoint exploitation or if you lack enough logs to rule it out. Sysdig observed attackers moving quickly from validation to environment variable harvesting and .env file access. (Sysdig)
Why CISA KEV changes prioritization
CVE score alone is not enough for patch priority. CVE-2026-33017 has both high severity and evidence of exploitation. CISA KEV inclusion means defenders should treat it as a known exploited vulnerability, not a theoretical issue. NVD’s KEV section lists the vulnerability name, date added, due date, and required action, and also records CISA’s SSVC fields showing active exploitation, automatable exploitation, and total technical impact. (NVD)
For practical prioritization, this CVE should outrank many high-scoring but non-exploited issues. The combination is unusually strong:
| Factor | CVE-2026-33017 status |
|---|---|
| Network reachable | Evet |
| Authentication required | Hayır |
| User interaction required | Hayır |
| Attack complexity | Düşük |
| Public technical detail | Evet |
| Active exploitation | Evet |
| CISA KEV | Evet |
| Sensitive runtime context | Often yes |
| Automation potential | Yüksek |
| Patch available | Yes, 1.9.0 or later |
If your vulnerability management process waits for a monthly cycle on a KEV-listed unauthenticated RCE in AI infrastructure, the process is not aligned with current attacker speed.
Related Langflow CVEs that explain the pattern
CVE-2026-33017 is easier to understand when compared with other Langflow vulnerabilities. The goal is not to imply that every Langflow issue has the same root cause. The goal is to show a recurring theme: AI workflow platforms combine user-facing interfaces, code execution, files, APIs, and credentials. Weak boundaries in any of those areas can become high-impact.
| CVE | Güvenlik Açığı | Exploit condition | Risk | Fix or mitigation |
|---|---|---|---|---|
| CVE-2025-3248 | Code injection in /api/v1/validate/code | Remote unauthenticated attacker could send crafted HTTP requests | Arbitrary code execution | Fixed before 1.3.0 by addressing the unauthenticated code validation path |
| CVE-2026-21445 | Missing authentication on monitor API endpoints | Unauthenticated access to sensitive monitor APIs | Conversation data exposure, transaction history access, destructive message deletion | Patched in 1.7.1 according to GitHub advisory and NVD |
| CVE-2026-33017 | Public flow build endpoint accepts attacker-controlled flow data | Unauthenticated public endpoint, versions before 1.9.0 | Server-side Python execution and potential secrets compromise | Upgrade to 1.9.0 or later |
| CVE-2026-33309 | Arbitrary file write through v2 file upload | Authenticated attacker can bypass filename containment | Arbitrary file write leading to RCE | Patched in 1.9.0 |
CVE-2025-3248 affected Langflow versions before 1.3.0 and involved code injection in /api/v1/validate/code, allowing a remote unauthenticated attacker to execute arbitrary code. It was also added to CISA KEV in 2025. (NVD)
CVE-2026-21445 involved missing authentication on critical monitor API endpoints. NVD says unauthenticated users could access sensitive conversation data, transaction histories, and destructive operations including message deletion, with a patch in version 1.7.0.dev45 and NVD configuration later noting versions before 1.7.1. (NVD)
CVE-2026-33309 affected Langflow’s v2 file upload path. GitHub’s advisory describes an arbitrary file write caused by multipart filename handling and insufficient storage-layer containment checks. The issue affected langflow >= 1.2.0, < 1.9.0 and was patched in 1.9.0. (GitHub)
The common theme is not “Langflow is uniquely bad.” The common theme is that AI workflow tools expose multiple boundaries at once: authentication, file storage, custom code, public sharing, API routes, flow graphs, and secrets. When those boundaries are tested one endpoint at a time, fixes can miss the underlying architectural class.
Why AI workflow tools attract attackers
Attackers like systems that satisfy three conditions: reachable, automatable, and valuable. Langflow deployments can satisfy all three.
Reachability comes from developer convenience. Many teams expose internal tools temporarily to test a workflow, share a demo, or connect a frontend. Automatable exploitation comes from stable HTTP APIs and predictable endpoints. Value comes from the secrets and integrations connected to the workflow runtime.
Sysdig noted that Langflow instances may be configured with API keys for OpenAI, Anthropic, AWS, and database connections, and that compromising one instance can provide lateral access to cloud accounts and data stores. (Sysdig) Trend Micro’s later cryptominer research shows that commodity operators are now scanning exposed AI application endpoints as another foothold, even when the payload itself is not AI-specific. (www.trendmicro.com)
The “AI” part is therefore not hype. The RCE primitive is traditional. The environment is not. The environment often concentrates credentials, tools, model access, and data movement in one place.
Detection strategy, endpoint plus behavior

A good detection plan has three layers.
The first layer is route-level detection. Watch for POSTA talepleri /api/v1/build_public_tmp/{flow_id}/flow, especially from public IPs, automation user agents, and unusual geographies. This layer is simple and fast, but it only catches the initial route.
The second layer is process behavior. Watch for Python processes spawning shells, running kıvrıl veya wget, reading .env, reading database files, or launching unknown binaries from /tmp ve /var/tmp.
The third layer is egress behavior. Watch for OAST domains, interactsh callbacks, unusual VPS destinations, HTTP C2, mining pools, and outbound traffic on ports commonly used by cryptominers.
| Katman | Example signal | Response |
|---|---|---|
| HTTP route | POST /api/v1/build_public_tmp/.../flow | Review body metadata if available, source IP, status code, timing |
| Application | Langflow errors around public flow build | Correlate with access logs and process behavior |
| Process | Python spawns shell or network tools | Treat as strong RCE signal |
| File access | Reads of .env, .db, /etc/passwd | Rotate secrets and investigate |
| Network | OAST, interactsh, unknown port 8080, port 8443 | Block, preserve flow logs, identify process owner |
| Kalıcılık | Cron changes, hidden files in /tmp, suspicious binaries | Rebuild host or container |
| Crypto mining | XMRig-like process or pool ports | Treat as confirmed compromise |
Sysdig’s detection guidance supports this layered view: behavior-level rules for sensitive file reads, OAST DNS lookups, inline shell execution by kıvrıl veya wget, and outbound C2 are valuable because they detect exploitation behavior rather than relying on a single CVE signature. (Sysdig)
A practical hardening baseline for Langflow
Hardening Langflow should not wait for the next CVE. Use CVE-2026-33017 as the forcing function to apply a stronger baseline.
| Kontrol | Recommended state |
|---|---|
| Versiyon | 1.9.0 or later, preferably current stable |
| Public exposure | No direct unauthenticated internet exposure |
| Reverse proxy | Authentication, TLS, request logging, rate limiting |
| Public flows | Disabled unless explicitly required and reviewed |
| Service account | Non-root, minimal filesystem permissions |
| Secrets | Inject only needed secrets, avoid broad .env dosyalar |
| Egress | Allowlist provider APIs and required services |
| Runtime | Detect Python spawning shell/network tools |
| Containers | Immutable image, read-only filesystem where possible |
| Filesystem | Restrict write paths, monitor /tmp ve /var/tmp |
| Logs | Preserve access, app, container, process, and egress logs |
| Ownership | Assign Langflow owner, patch SLA, data classification |
A hardened Docker Compose pattern should avoid privileged containers, avoid broad host mounts, and minimize secrets:
services:
langflow:
image: langflowai/langflow:1.10.1
user: "10001:10001"
read_only: true
tmpfs:
- /tmp:size=256m,noexec,nosuid,nodev
environment:
LANGFLOW_LOG_LEVEL: "info"
volumes:
- langflow_data:/app/data
ports:
- "127.0.0.1:7860:7860"
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
restart: unless-stopped
volumes:
langflow_data:
This example is not a universal production template. It shows the direction: bind to localhost behind a reverse proxy, run as non-root, avoid unnecessary Linux capabilities, reduce writable paths, and keep direct public exposure out of the default path.
Cloud and Kubernetes considerations
Kubernetes can make this vulnerability easier to miss. A Langflow pod may be exposed through an ingress, a LoadBalancer service, a port-forward left running in a jumpbox, or a temporary tunnel. The image tag may say latest, while the package inside the image may differ from what the tag suggests.
Start with exposure:
kubectl get svc -A \
-o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,TYPE:.spec.type,EXTERNAL-IP:.status.loadBalancer.ingress[*].ip,PORTS:.spec.ports[*].port' \
| grep -i langflow || true
kubectl get ingress -A | grep -i langflow || true
Then identify images:
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{" "}{.metadata.name}{" "}{range .spec.containers[*]}{.image}{" "}{end}{"\n"}{end}' \
| grep -i langflow || true
Then check runtime configuration. The exact commands vary by cluster policy, but the questions are stable:
| Question | Neden önemli |
|---|---|
| Is the service public | Public exposure turns a vulnerable endpoint into internet-scale risk |
| Is the pod running as root | RCE impact increases with privileges |
| Are secrets mounted as files | Attackers commonly read mounted secrets |
| Does the pod have cloud IAM permissions | RCE may become cloud control-plane access |
| Is egress unrestricted | Stage-2 payloads and exfiltration become easier |
| Are logs centralized | Incident response depends on retained telemetry |
| Does the namespace allow lateral movement | One pod compromise may reach databases and internal APIs |
If you use service meshes or API gateways, add route-level telemetry for public AI tooling. Do not assume internal AI builders are low risk because they are “developer tools.”
Safer vulnerability validation workflows
Security teams need to verify fixes. The hard part is doing it safely, especially for a vulnerability with public exploitation and trivial RCE characteristics.
A safe validation workflow should use:
| Method | Safer approach |
|---|---|
| Version check | Confirm installed package and image version |
| Patch behavior | Verify the public endpoint ignores external Veri in a controlled lab |
| Production validation | Avoid sending code execution payloads to production |
| Log validation | Confirm no recent access to vulnerable route |
| Runtime validation | Confirm no suspicious child processes or egress |
| Secret validation | Check whether exposed instance had access to sensitive keys |
| Regression | Add a test ensuring public flows cannot accept external flow definitions |
If your team uses AI-assisted security workflows, this is the point where automation can help, but only under authorization and guardrails. A platform such as Penligent’s AI pentesting workflow can be useful when the task is to map exposed assets, verify findings through controlled steps, collect evidence, and produce a report without turning every check into an ad hoc exploit attempt. The key is not “AI finds the bug.” The key is that validation, evidence, scope, and human approval stay inside one controlled process. (Penligent)
For regression tests in your own software, the principle is straightforward: public execution endpoints should reject or ignore executable structure supplied by the caller. A unit test can be designed around that invariant without including a dangerous payload.
def test_public_flow_build_does_not_accept_external_flow_definition(client, public_flow_id):
response = client.post(
f"/api/v1/build_public_tmp/{public_flow_id}/flow",
json={
"inputs": {"message": "hello"},
"data": {
"nodes": [
{
"id": "unexpected-node",
"data": {
"type": "CustomComponent",
"template": {
"code": {
"value": "raise RuntimeError('external flow data should not execute')"
}
},
},
}
],
"edges": [],
},
},
)
assert response.status_code in (200, 400, 422)
assert flow_execution_used_stored_definition(public_flow_id)
The important assertion is not the exact HTTP status. The important assertion is that caller-supplied flow structure cannot become the executed flow.
What not to do
Several responses look attractive but are incomplete.
Do not only block one IP list. Sysdig explicitly noted that observed source IPs may be proxies or VPS nodes rather than the true operator origin, and Trend Micro showed later infrastructure reuse with different campaign behavior. IPs are useful for hunting, not complete protection. (Sysdig)
Do not only patch without rotating secrets. If exploitation occurred, environment variables and .env files may have been read. Assume model keys, database credentials, vector database tokens, and cloud credentials could be exposed.
Do not leave Langflow public because “it is just an AI demo.” Attackers do not price your asset by its internal label. They price it by reachability and secrets.
Do not assume 1.8.2 is safe. The 1.8.2 confusion is specifically documented by JFrog and the related GitHub issue. Treat 1.9.0 or later as the remediation floor. (JFrog Security Research)
Do not rely on authentication alone for future design. CVE-2026-33017 happened in a feature that was designed to be public. Public features need strict input authority boundaries, not just login checks.
SSS
What is CVE-2026-33017 in plain terms
- CVE-2026-33017 is a critical Langflow vulnerability that allows unauthenticated remote code execution.
- The vulnerable path is the public flow build endpoint,
POST /api/v1/build_public_tmp/{flow_id}/flow. - The dangerous behavior is that attacker-supplied flow data could contain Python code and reach unsandboxed
exec()execution. - It affects Langflow versions before 1.9.0 and has been added to CISA’s Known Exploited Vulnerabilities catalog. (NVD)
Which Langflow versions are affected
- Treat all Langflow versions before 1.9.0 as affected.
- GitLab’s advisory lists “all versions before 1.9.0” as affected and 1.9.0 as fixed.
- PyPI shows
langflow 1.9.0was released on April 14, 2026, with newer releases available afterward. - In practice, teams should upgrade to a current stable release at or above 1.9.0 after testing compatibility. (GitLab Danışma Veritabanı)
Is Langflow 1.8.2 safe from CVE-2026-33017
- Do not treat 1.8.2 as safe.
- JFrog reported that although some public sources suggested 1.8.2 was patched, their testing found 1.8.2 still exploitable in both PyPI and Docker environments.
- The correct remediation floor is 1.9.0 or later.
- If you ran 1.8.2 on an exposed host, review logs and rotate credentials if exposure cannot be ruled out. (JFrog Security Research)
How do I check whether my Langflow instance was exposed
- Search web server, reverse proxy, container, and application logs for
POSTAtalepleri/api/v1/build_public_tmp/. - Check whether Langflow was reachable from the internet through a public IP, load balancer, ingress, tunnel, or reverse proxy.
- Confirm package versions inside the running environment, not only the image tag.
- Review whether the Langflow process had access to model keys, database strings, vector store credentials, cloud tokens, or mounted secrets.
What logs should defenders inspect first
- Reverse proxy access logs for
build_public_tmp. - Application logs around public flow build requests.
- Container stdout and stderr around the suspected window.
- Process execution logs, especially Python spawning shell commands.
- DNS and proxy logs for OAST, interactsh, and unusual outbound HTTP destinations.
- File access telemetry for
.env, database files,/etc/passwd, and mounted secrets. - Cron and
/tmpchanges if cryptominer activity is suspected.
Why are AI workflow tools attractive targets
- They often hold multiple secrets in one runtime.
- They connect models, databases, vector stores, internal APIs, and cloud services.
- They may be deployed by teams outside standard production security review.
- They often support custom components, tool calls, file uploads, and workflow execution.
- Attackers can use a traditional RCE primitive to reach AI-specific credentials and broader infrastructure.
Is blocking the vulnerable endpoint enough
- Blocking the route can reduce exposure, especially during emergency response.
- It is not a substitute for upgrading to 1.9.0 or later.
- It does not remove malware or persistence if exploitation already happened.
- It does not rotate credentials that may have been stolen.
- It does not fix broader execution-boundary risks in AI workflow infrastructure.
Closing judgment
CVE-2026-33017 is a traditional application security failure inside a modern AI workflow runtime. The exploit primitive is familiar: unauthenticated input reaches server-side code execution. The impact is modern: the compromised process may sit close to model keys, cloud credentials, database connections, vector stores, and agent workflows.
The right response is not complicated, but it must be complete. Upgrade Langflow to 1.9.0 or later. Remove direct public exposure. Review logs for the public flow build route. Hunt for process and egress behavior. Rotate secrets if exposure is possible. Rebuild compromised hosts. Then treat AI workflow builders as real infrastructure, with owners, patch SLAs, network boundaries, runtime detection, and evidence-based validation.
For teams building a repeatable security process around this class of issue, the broader lesson is that AI infrastructure needs the same discipline as any other production control plane: asset inventory, exposure management, safe verification, evidence capture, remediation tracking, and retesting. Penligent’s broader work on authorized AI-driven penetration testing sits in that operational category, but the technical priority here remains the same with or without any tool: verify the fix, reduce the blast radius, and assume exposed execution surfaces will be weaponized quickly. (Penligent)

