# Langflow: OS command injection (RCE) via arbitrary command in MCP stdio server configuration

Langflow's MCP stdio transport ran user-supplied command/args via bash -c with no allowlist, giving RCE on the host, reachable unauthenticated under default AUTO_LOGIN.

- Payout: Research
- Severity: critical
- Program: Langflow
- Found by: MosesOX, andifilhohub
- Disclosed: 2026-10-07
- CVE: CVE-2026-105697
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-w794-rj3p-xv45
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-w794-rj3p-xv45
- Tags: area:ai domain:ai domain:web impact:rce kind:research platform:ghsa sev:critical tech:python technique:incomplete-fix technique:source-review vuln:auth-bypass vuln:command-injection vuln:rce

**Target:** MCP stdio server configuration (REST API /api/v2/mcp/servers and MCP Tools component)
**Root cause:** MCPStdioClient._connect_to_server built StdioServerParameters with command="bash", args=["-c", f"exec {command_str} ..."] from unvalidated user-supplied command/args; the only check (_validate_node_installation) merely verified Node.js presence for npx.
**Steps:**
1. Obtain a token without credentials on a default instance: `curl -s http://127.0.0.1:7860/api/v1/auto_login` and read `access_token`.
2. POST the server config: `curl -s -X POST 'http://127.0.0.1:7860/api/v2/mcp/servers/testing' -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' --data-raw '{"command":"touch","args":["/tmp/pwned_langflow"]}'`.
3. Trigger connection (list servers, load tools, or run a flow); the process spawns via anyio.open_process before the MCP handshake, creating `/tmp/pwned_langflow` even if the UI reports startup failure.
4. Alternatively set Command=`touch`, Arguments=`/tmp/pwn` in Settings → MCP Servers → Add MCP Server (STDIO), or embed the value in a flow/tweak on 1.9.0–1.10.2.
**How found:** Reporter inspected the MCP stdio execution sink and noticed user-controlled command/args were passed into a bash -c wrapper with only an npx/Node.js presence check, then tested the settings page and REST API.
**Exploitation:** Attacker with UI/API access (or none under default AUTO_LOGIN) stores an MCP stdio server whose command is any OS command; Langflow wraps it in `bash -c "exec {command} ..."` and spawns it as the Langflow process user on connect, yielding arbitrary command execution / reverse shell.
**Escalation:** Default LANGFLOW_AUTO_LOGIN=true makes the endpoint reachable without an account; reporter found several internet-facing vulnerable instances.
**Insight:** MCP stdio configs are a command-execution primitive by design; audit every path a config can enter (API model, flow JSON, tweaks, deprecated components) because fixing only the REST validator leaves the execution sink exploitable via embedded flow configs.

