CVE-2026-105697
Langflow: OS command injection (RCE) via arbitrary command in MCP stdio server configuration
Langflow is a tool for building and deploying AI-powered agents and workflows. Before Langflow 1.10.3, the MCP stdio transport launched whatever command / args a user put in an MCP server configuration, with no allowlist and (before 1.10.3) wrapped in bash -c "exec {command} ...". Any user able to reach the MCP server settings ("Settings → MCP Servers → Add MCP Server", POST/PATCH /api/v2/mcp/servers/{server_name}) or to build a flow with the MCP Tools component could add a "server" whose command is an arbitrary OS command (touch, rm -rf, a reverse shell, ...). The command runs on the Langflow host as the Langflow process user as soon as Langflow tries to connect to the server (listing servers, loading tools, running the flow) — even when the UI then reports that the stdio server failed to start. With the default LANGFLOW_AUTO_LOGIN=true, GET /api/v1/auto_login hands out a token without credentials, so on an exposed instance running the default configuration this is reachable without an account. AUTO_LOGIN is documented as a development-only setting; with it disabled, any authenticated (non-admin) user can exploit it. This issue is fixed in Langflow 1.10.3, langflow-base 0.10.3, and lfx 1.10.3.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
9.9
Langflow: OS command injection (RCE) via arbitrary command in MCP stdio server configuration
Langflow is a tool for building and deploying AI-powered agents and workflows. Before Langflow 1.10.3, the MCP stdio transport launched whatever command / args a user put in an MCP server configuration, with no allowlist and (before 1.10.3) wrapped in bash -c "exec {command} ...". Any user able to reach the MCP server settings ("Settings → MCP Servers → Add MCP Server", POST/PATCH /api/v2/mcp/servers/{server_name}) or to build a flow with the MCP Tools component could add a "server" whose command is an arbitrary OS command (touch, rm -rf, a reverse shell, ...). The command runs on the Langflow host as the Langflow process user as soon as Langflow tries to connect to the server (listing servers, loading tools, running the flow) — even when the UI then reports that the stdio server failed to start. With the default LANGFLOW_AUTO_LOGIN=true, GET /api/v1/auto_login hands out a token without credentials, so on an exposed instance running the default configuration this is reachable without an account. AUTO_LOGIN is documented as a development-only setting; with it disabled, any authenticated (non-admin) user can exploit it. This issue is fixed in Langflow 1.10.3, langflow-base 0.10.3, and lfx 1.10.3.
- Record
CVE-2026-105697- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-02
EUVDEUVD-2026-92788
9.9
Langflow is a tool for building and deploying AI-powered agents and workflows. Before Langflow 1.10.3, the MCP stdio transport launched whatever command / args a user put in an MCP server configuration, with no allowlist and (before 1.10.3) wrapped in bash -c "exec {command} ...". Any user able to reach the MCP server settings ("Settings → MCP Servers → Add MCP Server", POST/PATCH /api/v2/mcp/servers/{server_name}) or to build a flow with the MCP Tools component could add a "server" whose command is an arbitrary OS command (touch, rm -rf, a reverse shell, ...). The command runs on the Langflow host as the Langflow process user as soon as Langflow tries to connect to the server (listing servers, loading tools, running the flow) — even when the UI then reports that the stdio server failed to start. With the default LANGFLOW_AUTO_LOGIN=true, GET /api/v1/auto_login hands out a token without credentials, so on an exposed instance running the default configuration this is reachable without an account. AUTO_LOGIN is documented as a development-only setting; with it disabled, any authenticated (non-admin) user can exploit it. This issue is fixed in Langflow 1.10.3, langflow-base 0.10.3, and lfx 1.10.3.
- Record
EUVD-2026-92788- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-w794-rj3p-xv45
9.9
Langflow: OS command injection (RCE) via arbitrary command in MCP stdio server configuration
Summary
Before Langflow 1.10.3, the MCP stdio transport launched whatever command / args a user put in an MCP server configuration, with no allowlist and (before 1.10.3) wrapped in bash -c "exec {command} ...". Any user able to reach the MCP server settings ("Settings → MCP Servers → Add MCP Server", POST/PATCH /api/v2/mcp/servers/{server_name}) or to build a flow with the MCP Tools component could add a "server" whose command is an arbitrary OS command (touch, rm -rf, a reverse shell, ...). The command runs on the Langflow host as the Langflow process user as soon as Langflow tries to connect to the server (listing servers, loading tools, running the flow) — even when the UI then reports that the stdio server failed to start.
With the default LANGFLOW_AUTO_LOGIN=true, GET /api/v1/auto_login hands out a token without credentials, so on an exposed instance running the default configuration this is reachable without an account. AUTO_LOGIN is documented as a development-only setting; with it disabled, any authenticated (non-admin) user can exploit it.
The issue was fixed in two steps and is fully fixed in Langflow 1.10.3 (and 1.11.0+):
- 1.9.0 — #12290 added a command allowlist and argument/env validation to the REST model (
MCPServerConfig), blocking the "Add MCP Server" vector reported here. - 1.10.3 — #14036 applied the same policy at the execution sink (
lfx.base.mcp.util), including configs embedded in flows / tweaks and the final pre-spawn boundary, and removed thebash -cwrapper (the process is now exec'd directly, without a shell).
Affected versions
| Package (PyPI) | Vulnerable | Patched |
|---|---|---|
| langflow | >= 1.1.2, < 1.10.3 | 1.10.3 |
| langflow-base | >= 0.1.2, < 0.10.3 | 0.10.3 |
| lfx | < 1.10.3 | 1.10.3 |
| Release | State |
|---|---|
| 1.1.2 – 1.4.x | MCP Stdio component (added in #5148) runs StdioServerParameters(command=..., args=...) from the component's command field with no validation. |
| 1.5.0 – 1.8.x | "Add MCP Server" settings page and /api/v2/mcp/servers API added (#8388). Stored stdio configs are launched via bash -c "exec {command_str} ..." with no validation. The PoC below works as-is. |
| 1.9.0 – 1.10.2 | #12290: POST/PATCH /api/v2/mcp/servers reject commands outside the allowlist. The execution sink still has no validation and still uses bash -c, so configs that do not go through MCPServerConfig (for example an MCP Tools component value embedded in a flow or passed as a tweak) can still execute arbitrary commands. |
| 1.10.3+ | #14036: one shared policy (lfx.base.mcp.security.validate_mcp_stdio_config) is enforced at the API, at flow execution and right before the process is spawned; no shell is used. Fixed. |
Details
Vulnerable sink (src/lfx/src/lfx/base/mcp/util.py, MCPStdioClient._connect_to_server, before 1.10.3):
server_params = StdioServerParameters(
command="bash",
args=["-c", f"exec {command_str} || echo 'Command failed with exit code $?' >&2"],
env=env_data,
)
command_str is built from the user's command + args. The only "validation" before 1.9.0 was _validate_node_installation, which only checks that Node.js is installed when the command contains npx. The MCP SDK then starts the process with anyio.open_process, so the command runs before any MCP handshake — which is why it executes even if the UI shows "failed to start".
PoC (as reported, Langflow 1.5.0 – 1.8.x)
In "Add MCP Server" → STDIO, add:
Name - Test
Command - touch
Arguments - /tmp/pwn
Or through the API, using a token from auto_login (default configuration):
TOKEN=$(curl -s http://127.0.0.1:7860/api/v1/auto_login | python3 -c 'import sys,json;print(json.load(sys.stdin)["access_token"])')
curl -s -X POST 'http://127.0.0.1:7860/api/v2/mcp/servers/testing' \
-H "Authorization: Bearer $TOKEN" \
-H…
- Record
GHSA-w794-rj3p-xv45- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-02
NVD
9.9
Langflow is a tool for building and deploying AI-powered agents and workflows. Before Langflow 1.10.3, the MCP stdio transport launched whatever command / args a user put in an MCP server configuration, with no allowlist and (before 1.10.3) wrapped in bash -c "exec {command} ...". Any user able to reach the MCP server settings ("Settings → MCP Servers → Add MCP Server", POST/PATCH /api/v2/mcp/servers/{server_name}) or to build a flow with the MCP Tools component could add a "server" whose command is an arbitrary OS command (touch, rm -rf, a reverse shell, ...). The command runs on the Langflow host as the Langflow process user as soon as Langflow tries to connect to the server (listing servers, loading tools, running the flow) — even when the UI then reports that the stdio server failed to start. With the default LANGFLOW_AUTO_LOGIN=true, GET /api/v1/auto_login hands out a token without credentials, so on an exposed instance running the default configuration this is reachable without an account. AUTO_LOGIN is documented as a development-only setting; with it disabled, any authenticated (non-admin) user can exploit it. This issue is fixed in Langflow 1.10.3, langflow-base 0.10.3, and lfx 1.10.3.
- Record
CVE-2026-105697- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-02
OSV
9.9
Langflow: OS command injection (RCE) via arbitrary command in MCP stdio server configuration
Langflow is a tool for building and deploying AI-powered agents and workflows. Before Langflow 1.10.3, the MCP stdio transport launched whatever command / args a user put in an MCP server configuration, with no allowlist and (before 1.10.3) wrapped in bash -c "exec {command} ...". Any user able to reach the MCP server settings ("Settings → MCP Servers → Add MCP Server", POST/PATCH /api/v2/mcp/servers/{server_name}) or to build a flow with the MCP Tools component could add a "server" whose command is an arbitrary OS command (touch, rm -rf, a reverse shell, ...). The command runs on the Langflow host as the Langflow process user as soon as Langflow tries to connect to the server (listing servers, loading tools, running the flow) — even when the UI then reports that the stdio server failed to start. With the default LANGFLOW_AUTO_LOGIN=true, GET /api/v1/auto_login hands out a token without credentials, so on an exposed instance running the default configuration this is reachable without an account. AUTO_LOGIN is documented as a development-only setting; with it disabled, any authenticated (non-admin) user can exploit it. This issue is fixed in Langflow 1.10.3, langflow-base 0.10.3, and lfx 1.10.3.
- Record
CVE-2026-105697- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-04
OSVGHSA-w794-rj3p-xv45
9.9
Langflow: OS command injection (RCE) via arbitrary command in MCP stdio server configuration
Summary
Before Langflow 1.10.3, the MCP stdio transport launched whatever command / args a user put in an MCP server configuration, with no allowlist and (before 1.10.3) wrapped in bash -c "exec {command} ...". Any user able to reach the MCP server settings ("Settings → MCP Servers → Add MCP Server", POST/PATCH /api/v2/mcp/servers/{server_name}) or to build a flow with the MCP Tools component could add a "server" whose command is an arbitrary OS command (touch, rm -rf, a reverse shell, ...). The command runs on the Langflow host as the Langflow process user as soon as Langflow tries to connect to the server (listing servers, loading tools, running the flow) — even when the UI then reports that the stdio server failed to start.
With the default LANGFLOW_AUTO_LOGIN=true, GET /api/v1/auto_login hands out a token without credentials, so on an exposed instance running the default configuration this is reachable without an account. AUTO_LOGIN is documented as a development-only setting; with it disabled, any authenticated (non-admin) user can exploit it.
The issue was fixed in two steps and is fully fixed in Langflow 1.10.3 (and 1.11.0+):
- 1.9.0 — #12290 added a command allowlist and argument/env validation to the REST model (
MCPServerConfig), blocking the "Add MCP Server" vector reported here. - 1.10.3 — #14036 applied the same policy at the execution sink (
lfx.base.mcp.util), including configs embedded in flows / tweaks and the final pre-spawn boundary, and removed thebash -cwrapper (the process is now exec'd directly, without a shell).
Affected versions
| Package (PyPI) | Vulnerable | Patched |
|---|---|---|
| langflow | >= 1.1.2, < 1.10.3 | 1.10.3 |
| langflow-base | >= 0.1.2, < 0.10.3 | 0.10.3 |
| lfx | < 1.10.3 | 1.10.3 |
| Release | State |
|---|---|
| 1.1.2 – 1.4.x | MCP Stdio component (added in #5148) runs StdioServerParameters(command=..., args=...) from the component's command field with no validation. |
| 1.5.0 – 1.8.x | "Add MCP Server" settings page and /api/v2/mcp/servers API added (#8388). Stored stdio configs are launched via bash -c "exec {command_str} ..." with no validation. The PoC below works as-is. |
| 1.9.0 – 1.10.2 | #12290: POST/PATCH /api/v2/mcp/servers reject commands outside the allowlist. The execution sink still has no validation and still uses bash -c, so configs that do not go through MCPServerConfig (for example an MCP Tools component value embedded in a flow or passed as a tweak) can still execute arbitrary commands. |
| 1.10.3+ | #14036: one shared policy (lfx.base.mcp.security.validate_mcp_stdio_config) is enforced at the API, at flow execution and right before the process is spawned; no shell is used. Fixed. |
Details
Vulnerable sink (src/lfx/src/lfx/base/mcp/util.py, MCPStdioClient._connect_to_server, before 1.10.3):
server_params = StdioServerParameters(
command="bash",
args=["-c", f"exec {command_str} || echo 'Command failed with exit code $?' >&2"],
env=env_data,
)
command_str is built from the user's command + args. The only "validation" before 1.9.0 was _validate_node_installation, which only checks that Node.js is installed when the command contains npx. The MCP SDK then starts the process with anyio.open_process, so the command runs before any MCP handshake — which is why it executes even if the UI shows "failed to start".
PoC (as reported, Langflow 1.5.0 – 1.8.x)
In "Add MCP Server" → STDIO, add:
Name - Test
Command - touch
Arguments - /tmp/pwn
Or through the API, using a token from auto_login (default configuration):
TOKEN=$(curl -s http://127.0.0.1:7860/api/v1/auto_login | python3 -c 'import sys,json;print(json.load(sys.stdin)["access_token"])')
curl -s -X POST 'http://127.0.0.1:7860/api/v2/mcp/servers/testing' \
-H "Authorization: Bearer $TOKEN" \
-H…
- Record
GHSA-w794-rj3p-xv45- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-02
OSVPYSEC-2026-4237
9.9
Langflow: OS command injection (RCE) via arbitrary command in MCP stdio server configuration
Summary
Before Langflow 1.10.3, the MCP stdio transport launched whatever command / args a user put in an MCP server configuration, with no allowlist and (before 1.10.3) wrapped in bash -c "exec {command} ...". Any user able to reach the MCP server settings ("Settings → MCP Servers → Add MCP Server", POST/PATCH /api/v2/mcp/servers/{server_name}) or to build a flow with the MCP Tools component could add a "server" whose command is an arbitrary OS command (touch, rm -rf, a reverse shell, ...). The command runs on the Langflow host as the Langflow process user as soon as Langflow tries to connect to the server (listing servers, loading tools, running the flow) — even when the UI then reports that the stdio server failed to start.
With the default LANGFLOW_AUTO_LOGIN=true, GET /api/v1/auto_login hands out a token without credentials, so on an exposed instance running the default configuration this is reachable without an account. AUTO_LOGIN is documented as a development-only setting; with it disabled, any authenticated (non-admin) user can exploit it.
The issue was fixed in two steps and is fully fixed in Langflow 1.10.3 (and 1.11.0+):
- 1.9.0 — #12290 added a command allowlist and argument/env validation to the REST model (
MCPServerConfig), blocking the "Add MCP Server" vector reported here. - 1.10.3 — #14036 applied the same policy at the execution sink (
lfx.base.mcp.util), including configs embedded in flows / tweaks and the final pre-spawn boundary, and removed thebash -cwrapper (the process is now exec'd directly, without a shell).
Affected versions
| Package (PyPI) | Vulnerable | Patched |
|---|---|---|
| langflow | >= 1.1.2, < 1.10.3 | 1.10.3 |
| langflow-base | >= 0.1.2, < 0.10.3 | 0.10.3 |
| lfx | < 1.10.3 | 1.10.3 |
| Release | State |
|---|---|
| 1.1.2 – 1.4.x | MCP Stdio component (added in #5148) runs StdioServerParameters(command=..., args=...) from the component's command field with no validation. |
| 1.5.0 – 1.8.x | "Add MCP Server" settings page and /api/v2/mcp/servers API added (#8388). Stored stdio configs are launched via bash -c "exec {command_str} ..." with no validation. The PoC below works as-is. |
| 1.9.0 – 1.10.2 | #12290: POST/PATCH /api/v2/mcp/servers reject commands outside the allowlist. The execution sink still has no validation and still uses bash -c, so configs that do not go through MCPServerConfig (for example an MCP Tools component value embedded in a flow or passed as a tweak) can still execute arbitrary commands. |
| 1.10.3+ | #14036: one shared policy (lfx.base.mcp.security.validate_mcp_stdio_config) is enforced at the API, at flow execution and right before the process is spawned; no shell is used. Fixed. |
Details
Vulnerable sink (src/lfx/src/lfx/base/mcp/util.py, MCPStdioClient._connect_to_server, before 1.10.3):
server_params = StdioServerParameters(
command="bash",
args=["-c", f"exec {command_str} || echo 'Command failed with exit code $?' >&2"],
env=env_data,
)
command_str is built from the user's command + args. The only "validation" before 1.9.0 was _validate_node_installation, which only checks that Node.js is installed when the command contains npx. The MCP SDK then starts the process with anyio.open_process, so the command runs before any MCP handshake — which is why it executes even if the UI shows "failed to start".
PoC (as reported, Langflow 1.5.0 – 1.8.x)
In "Add MCP Server" → STDIO, add:
Name - Test
Command - touch
Arguments - /tmp/pwn
Or through the API, using a token from auto_login (default configuration):
TOKEN=$(curl -s http://127.0.0.1:7860/api/v1/auto_login | python3 -c 'import sys,json;print(json.load(sys.stdin)["access_token"])')
curl -s -X POST 'http://127.0.0.1:7860/api/v2/mcp/servers/testing' \
-H "Authorization: Bearer $TOKEN" \
-H…
- Record
PYSEC-2026-4237- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Updated
- 2026-11-02
OSVPYSEC-2026-4239
9.9
Langflow: OS command injection (RCE) via arbitrary command in MCP stdio server configuration
Summary
Before Langflow 1.10.3, the MCP stdio transport launched whatever command / args a user put in an MCP server configuration, with no allowlist and (before 1.10.3) wrapped in bash -c "exec {command} ...". Any user able to reach the MCP server settings ("Settings → MCP Servers → Add MCP Server", POST/PATCH /api/v2/mcp/servers/{server_name}) or to build a flow with the MCP Tools component could add a "server" whose command is an arbitrary OS command (touch, rm -rf, a reverse shell, ...). The command runs on the Langflow host as the Langflow process user as soon as Langflow tries to connect to the server (listing servers, loading tools, running the flow) — even when the UI then reports that the stdio server failed to start.
With the default LANGFLOW_AUTO_LOGIN=true, GET /api/v1/auto_login hands out a token without credentials, so on an exposed instance running the default configuration this is reachable without an account. AUTO_LOGIN is documented as a development-only setting; with it disabled, any authenticated (non-admin) user can exploit it.
The issue was fixed in two steps and is fully fixed in Langflow 1.10.3 (and 1.11.0+):
- 1.9.0 — #12290 added a command allowlist and argument/env validation to the REST model (
MCPServerConfig), blocking the "Add MCP Server" vector reported here. - 1.10.3 — #14036 applied the same policy at the execution sink (
lfx.base.mcp.util), including configs embedded in flows / tweaks and the final pre-spawn boundary, and removed thebash -cwrapper (the process is now exec'd directly, without a shell).
Affected versions
| Package (PyPI) | Vulnerable | Patched |
|---|---|---|
| langflow | >= 1.1.2, < 1.10.3 | 1.10.3 |
| langflow-base | >= 0.1.2, < 0.10.3 | 0.10.3 |
| lfx | < 1.10.3 | 1.10.3 |
| Release | State |
|---|---|
| 1.1.2 – 1.4.x | MCP Stdio component (added in #5148) runs StdioServerParameters(command=..., args=...) from the component's command field with no validation. |
| 1.5.0 – 1.8.x | "Add MCP Server" settings page and /api/v2/mcp/servers API added (#8388). Stored stdio configs are launched via bash -c "exec {command_str} ..." with no validation. The PoC below works as-is. |
| 1.9.0 – 1.10.2 | #12290: POST/PATCH /api/v2/mcp/servers reject commands outside the allowlist. The execution sink still has no validation and still uses bash -c, so configs that do not go through MCPServerConfig (for example an MCP Tools component value embedded in a flow or passed as a tweak) can still execute arbitrary commands. |
| 1.10.3+ | #14036: one shared policy (lfx.base.mcp.security.validate_mcp_stdio_config) is enforced at the API, at flow execution and right before the process is spawned; no shell is used. Fixed. |
Details
Vulnerable sink (src/lfx/src/lfx/base/mcp/util.py, MCPStdioClient._connect_to_server, before 1.10.3):
server_params = StdioServerParameters(
command="bash",
args=["-c", f"exec {command_str} || echo 'Command failed with exit code $?' >&2"],
env=env_data,
)
command_str is built from the user's command + args. The only "validation" before 1.9.0 was _validate_node_installation, which only checks that Node.js is installed when the command contains npx. The MCP SDK then starts the process with anyio.open_process, so the command runs before any MCP handshake — which is why it executes even if the UI shows "failed to start".
PoC (as reported, Langflow 1.5.0 – 1.8.x)
In "Add MCP Server" → STDIO, add:
Name - Test
Command - touch
Arguments - /tmp/pwn
Or through the API, using a token from auto_login (default configuration):
TOKEN=$(curl -s http://127.0.0.1:7860/api/v1/auto_login | python3 -c 'import sys,json;print(json.load(sys.stdin)["access_token"])')
curl -s -X POST 'http://127.0.0.1:7860/api/v2/mcp/servers/testing' \
-H "Authorization: Bearer $TOKEN" \
-H…
- Record
PYSEC-2026-4239- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Updated
- 2026-11-02
OSVPYSEC-2026-4241
9.9
Langflow: OS command injection (RCE) via arbitrary command in MCP stdio server configuration
Summary
Before Langflow 1.10.3, the MCP stdio transport launched whatever command / args a user put in an MCP server configuration, with no allowlist and (before 1.10.3) wrapped in bash -c "exec {command} ...". Any user able to reach the MCP server settings ("Settings → MCP Servers → Add MCP Server", POST/PATCH /api/v2/mcp/servers/{server_name}) or to build a flow with the MCP Tools component could add a "server" whose command is an arbitrary OS command (touch, rm -rf, a reverse shell, ...). The command runs on the Langflow host as the Langflow process user as soon as Langflow tries to connect to the server (listing servers, loading tools, running the flow) — even when the UI then reports that the stdio server failed to start.
With the default LANGFLOW_AUTO_LOGIN=true, GET /api/v1/auto_login hands out a token without credentials, so on an exposed instance running the default configuration this is reachable without an account. AUTO_LOGIN is documented as a development-only setting; with it disabled, any authenticated (non-admin) user can exploit it.
The issue was fixed in two steps and is fully fixed in Langflow 1.10.3 (and 1.11.0+):
- 1.9.0 — #12290 added a command allowlist and argument/env validation to the REST model (
MCPServerConfig), blocking the "Add MCP Server" vector reported here. - 1.10.3 — #14036 applied the same policy at the execution sink (
lfx.base.mcp.util), including configs embedded in flows / tweaks and the final pre-spawn boundary, and removed thebash -cwrapper (the process is now exec'd directly, without a shell).
Affected versions
| Package (PyPI) | Vulnerable | Patched |
|---|---|---|
| langflow | >= 1.1.2, < 1.10.3 | 1.10.3 |
| langflow-base | >= 0.1.2, < 0.10.3 | 0.10.3 |
| lfx | < 1.10.3 | 1.10.3 |
| Release | State |
|---|---|
| 1.1.2 – 1.4.x | MCP Stdio component (added in #5148) runs StdioServerParameters(command=..., args=...) from the component's command field with no validation. |
| 1.5.0 – 1.8.x | "Add MCP Server" settings page and /api/v2/mcp/servers API added (#8388). Stored stdio configs are launched via bash -c "exec {command_str} ..." with no validation. The PoC below works as-is. |
| 1.9.0 – 1.10.2 | #12290: POST/PATCH /api/v2/mcp/servers reject commands outside the allowlist. The execution sink still has no validation and still uses bash -c, so configs that do not go through MCPServerConfig (for example an MCP Tools component value embedded in a flow or passed as a tweak) can still execute arbitrary commands. |
| 1.10.3+ | #14036: one shared policy (lfx.base.mcp.security.validate_mcp_stdio_config) is enforced at the API, at flow execution and right before the process is spawned; no shell is used. Fixed. |
Details
Vulnerable sink (src/lfx/src/lfx/base/mcp/util.py, MCPStdioClient._connect_to_server, before 1.10.3):
server_params = StdioServerParameters(
command="bash",
args=["-c", f"exec {command_str} || echo 'Command failed with exit code $?' >&2"],
env=env_data,
)
command_str is built from the user's command + args. The only "validation" before 1.9.0 was _validate_node_installation, which only checks that Node.js is installed when the command contains npx. The MCP SDK then starts the process with anyio.open_process, so the command runs before any MCP handshake — which is why it executes even if the UI shows "failed to start".
PoC (as reported, Langflow 1.5.0 – 1.8.x)
In "Add MCP Server" → STDIO, add:
Name - Test
Command - touch
Arguments - /tmp/pwn
Or through the API, using a token from auto_login (default configuration):
TOKEN=$(curl -s http://127.0.0.1:7860/api/v1/auto_login | python3 -c 'import sys,json;print(json.load(sys.stdin)["access_token"])')
curl -s -X POST 'http://127.0.0.1:7860/api/v2/mcp/servers/testing' \
-H "Authorization: Bearer $TOKEN" \
-H…
- Record
PYSEC-2026-4241- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
langflowPyPI |
1.1.2 up to 1.10.3 | 1.10.3 |
langflow-basePyPI |
0.1.2 up to 0.10.3 | 0.10.3 |
lfxPyPI |
before 1.10.3 | 1.10.3 |
langflowPyPI |
1.1.2 up to 1.10.3, plus listed versions 1.1.31.1.41.1.4.post11.10.01.10.0rc0 Show 45 moreShow less1.10.11.10.1rc01.10.1rc31.10.21.10.2rc41.10.3rc01.2.01.3.01.3.11.3.21.3.31.3.41.4.01.4.11.4.21.4.31.5.01.5.0.post11.5.0.post21.5.11.6.01.6.11.6.21.6.31.6.41.6.51.6.61.6.71.6.81.6.91.7.01.7.11.7.21.7.31.8.01.8.0rc01.8.0rc11.8.0rc21.8.0rc31.8.0rc41.8.0rc51.8.0rc61.8.11.8.21.8.3 |
1.10.3 |
langflow-basePyPI |
0.1.2 up to 0.10.3, plus listed versions 0.1.30.1.40.1.4.post10.10.00.10.0rc0 Show 45 moreShow less0.10.10.10.1rc00.10.1rc30.10.20.10.2rc40.10.3rc00.2.00.3.00.3.10.3.20.3.30.3.40.4.00.4.10.4.20.4.30.5.00.5.0.post10.5.0.post20.5.10.6.00.6.10.6.20.6.30.6.40.6.50.6.60.6.70.6.80.6.90.7.00.7.10.7.20.7.30.8.00.8.0rc00.8.0rc10.8.0rc20.8.0rc30.8.0rc40.8.0rc50.8.0rc60.8.10.8.20.8.3 |
0.10.3 |
lfxPyPI |
before 1.10.3, plus listed versions 0.1.00.1.10.1.100.1.110.1.13 Show 41 moreShow less0.1.20.1.30.1.40.1.50.1.60.1.70.1.80.1.90.2.00.2.10.2.20.3.00.3.0rc00.3.0rc10.3.0rc20.3.0rc30.3.0rc40.3.0rc50.3.0rc60.3.10.3.20.3.30.3.3rc00.3.40.4.00.4.10.4.20.4.30.4.3rc00.4.40.4.50.4.60.4.6rc01.10.01.10.0rc01.10.11.10.1rc01.10.1rc31.10.21.10.2rc41.10.3rc0 |
1.10.3 |
Public exploits
Links only. Every CVE stores no exploit code.
| Source | Link | Date |
|---|---|---|
| PoC in GitHub | Iceman2050/mcp-patch-gap-scanner | 2026-10-18 |
History
| Recorded | Changed | Sources |
|---|---|---|
| facts | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV, PoC in GitHub |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-105697 is a critical vulnerability (CVSS 9.9) in Langflow-ai Langflow, published October 5, 2026. Public exploit code exists. EPSS puts the chance of exploitation in the next 30 days at 0.95%, the 61st percentile. Fixed in langflow 1.10.3.
References
github.com/langflow-ai/langflow/security/advisories/GHSA-w794-rj3p-xv45
github.com/langflow-ai/langflow/security/advisories/GHSA-7w94-79vh-5mr2
github.com/langflow-ai/langflow/pull/12290
github.com/langflow-ai/langflow/pull/14036
github.com/langflow-ai/langflow/commit/eba285edf1dd4a33bf23a9cb8113c991fcdf3d1d
github.com/langflow-ai/langflow/commit/efbc4a16e639409d938a4883463d27ef0bc637a0
Show 10 moreShow less
github.com/langflow-ai/langflow/releases/tag/v1.10.3
ox.security/blog/mcp-supply-chain-advisory-rce-vulnerabilities-across-the-ai-ecosystem
ox.security/blog/the-mother-of-all-ai-supply-chains-critical-systemic-vulnerability-at-the-core-of-the-mcp
nvd.nist.gov/vuln/detail/CVE-2026-105697
github.com/advisories/GHSA-w794-rj3p-xv45
github.com/CVEProject/cvelistV5/tree/main/cves/2026/105xxx/CVE-2026-105697.json
github.com/langflow-ai/langflow
pypi.org/project/langflow
pypi.org/project/langflow-base
pypi.org/project/lfx
Left out here: 22 versions and the rest of 5 source descriptions. The JSON record has them.