## https://sploitus.com/exploit?id=8A390AA6-FCBA-5C9C-901C-5D94D4A03A15
# CVE-2026-33017 โ Langflow Unauthenticated RCE Nuclei Template
[](#)
[](#)
[](#)
[](https://github.com/lopseg)
Nuclei template that detects **CVE-2026-33017** โ an unauthenticated
remote-code-execution vulnerability in **Langflow โค 1.8.2** reachable through
the public flow-build endpoint:
```
POST /api/v1/build_public_tmp/{flow_id}/flow
```
The vulnerable handler accepts an attacker-controlled `data` flow graph and
passes `data.nodes[].data.node.template.code.value` straight into Python
`exec()` during graph build, with no sandboxing. The fix (โฅ 1.9.0) drops the
`data` parameter from the handler signature, so a patched build rejects the
same request at FastAPI's validation layer with HTTP 422.
---
## How the template decides
The template is **non-destructive**. It sends an inert payload against a
**zero-UUID** flow ID, so it cannot reach `exec()` even on a vulnerable host.
It distinguishes the vulnerable handler from the patched one by the HTTP
response signature alone.
| Stage | Request | What it tells you |
|------:|---------|-------------------|
| 1 | `GET /api/v1/version` | Confirms the target is Langflow and extracts the build version. |
| 2 | `POST /api/v1/build_public_tmp/00000000-0000-0000-0000-000000000000/flow` with a body containing the `data` field and an inert `template.code.value` | Routing decision below. |
Routing for stage 2:
| Status | Body contains | Verdict |
|-------:|---------------|---------|
| `404` | `flow` / `public` | **VULNERABLE** โ handler accepted `data`, the lookup then failed because the UUID is fake. |
| `200` | `job_id` / `build` / `task` | **VULNERABLE** โ handler accepted `data` and entered the build path. |
| `5xx` | `exec` / `Component` / `traceback` | **VULNERABLE** โ handler reached the exec code path before failing. |
| `422` | `Field required` / `extra` / `data` | **PATCHED** โ handler signature no longer accepts `data`. |
A real RCE confirmation still requires (a) a **real PUBLIC flow UUID** on
the target and (b) an **out-of-band callback** (DNS/HTTP). That step is **not**
included here on purpose โ this template is the safe pre-check that decides
whether running an active exploit makes sense at all.
---
## Usage
Single host:
```bash
nuclei -t CVE-2026-33017.yaml -u https://target.example.com
```
Bulk scan from a list:
```bash
nuclei -t CVE-2026-33017.yaml -l targets.txt -rl 20 -c 10
```
With debug output (see the raw requests/responses):
```bash
nuclei -t CVE-2026-33017.yaml -u https://target.example.com -debug-req -debug-resp
```
Validate the template locally before running it:
```bash
nuclei -validate -t CVE-2026-33017.yaml
```
---
## Example output
Vulnerable target:
```
[CVE-2026-33017] [http] [critical] https://target.example.com [vulnerable-flow-not-found] ["1.8.2","base"]
```
Patched target โ no finding emitted (422 response does not match any rule).
---
## Finding candidates
Common discovery queries for Langflow hosts (use only against assets you are
authorized to test):
- Shodan: `http.title:"Langflow"`
- FOFA: `app="Langflow"`
- Google: `intitle:"Langflow" inurl:"/flows"`
---
## Vulnerability details
- **CVE**: CVE-2026-33017
- **CWE**: CWE-94 (Improper Control of Generation of Code)
- **CVSS 3.1**: 9.3 โ `AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H`
- **Affected**: Langflow โค 1.8.2
- **Fixed in**: Langflow โฅ 1.9.0
- **Vector**: Network, unauthenticated, no user interaction
- **Impact**: Remote code execution as the Langflow process user
### Root cause (short)
In vulnerable builds the public handler is declared roughly as:
```python
@router.post("/build_public_tmp/{flow_id}/flow")
async def build_public_flow(flow_id: UUID, data: FlowDataRequest | None = None, ...):
...
await verify_public_flow_and_get_user(flow_id, ...)
...
# data.nodes[].data.node.template.code.value reaches exec() in the
# Component build path
```
`data` is attacker-controlled. The patched handler removes the parameter
entirely and forces `data=None`, which is why a request that includes a
`data` body field is rejected with 422 on patched builds.
---
## Remediation
1. Upgrade Langflow to **โฅ 1.9.0**.
2. If you cannot upgrade immediately, block `/api/v1/build_public_tmp/` at
the reverse proxy.
3. Set `LANGFLOW_AUTO_LOGIN=False`, configure superuser credentials, and
rotate `LANGFLOW_SECRET_KEY`.
4. Audit existing flows โ `access_type=PUBLIC` flows are the ones an
attacker would target in the URL.
---
## References
- GitHub Advisory:
- SonicWall write-up:
- Patched handler source:
---
## Legal & disclosure
This template is published for **defensive security and authorized
testing only**. Running it against systems you do not own or do not have
explicit written permission to test is illegal in most jurisdictions and
violates platform terms of service.
By using this template you agree that:
- You will only scan assets you own or are explicitly authorized to test
(bug-bounty scope, signed pentest engagement, internal asset inventory).
- The author is not responsible for misuse.
- The template is provided **as-is**, without warranty.
---
## Author
**lopseg** โ
Pull requests and issues welcome.
## License
MIT