Every CVE Search/ Get API key

CVE-2026-105697

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

9.9 CriticalPublic exploitFix available

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

0.95%Up 0.6 points since Oct 6, 2026
90%50%10%1%

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 CriticalCVSS: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 CriticalCVSS: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 the bash -c wrapper (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 CriticalCVSS: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 CriticalCVSS: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 CriticalCVSS: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 the bash -c wrapper (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 CriticalCVSS: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 the bash -c wrapper (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 CriticalCVSS: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 the bash -c wrapper (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 CriticalCVSS: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 the bash -c wrapper (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 CriticalCVSS: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

Affected packages
PackageAffectedFixed
langflow
PyPI
1.1.2 up to 1.10.3
1.10.3
langflow-base
PyPI
0.1.2 up to 0.10.3
0.10.3
lfx
PyPI
before 1.10.3
1.10.3
langflow
PyPI
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 less
1.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-base
PyPI
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 less
0.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
lfx
PyPI
before 1.10.3, plus listed versions
0.1.00.1.10.1.100.1.110.1.13
Show 41 moreShow less
0.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.

Public exploits
SourceLinkDate
PoC in GitHubIceman2050/mcp-patch-gap-scanner2026-10-18

History

History
RecordedChangedSources
factsOSV
first indexedCVE 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

Show 10 moreShow less
This page doesn't list everything

Left out here: 22 versions and the rest of 5 source descriptions. The JSON record has them.

MoveEnter Open