FlawOpen

flawopen.com/Teardowns/cve-2026-105697-langflow-mcp-stdio-command-injection

● CVE-2026-105697 · CVSS 9.9[1] · Crítica
Investigación · FlawOpen

CVE-2026-105697: inyección de comandos MCP en Langflow

Antes de la versión 1.10.3, Langflow enviaba la configuración MCP stdio a un proceso iniciado mediante un shell. En una instancia expuesta con LANGFLOW_AUTO_LOGIN=true, un atacante podía obtener un token sin credenciales; con el inicio automático desactivado, un usuario autenticado que no fuera administrador aún podía alcanzar la ejecución de comandos en el host. La versión 1.10.3 valida todas las rutas, incluso justo antes de iniciar el proceso, y lo ejecuta sin shell.[1], [2], [3]

Vector CVSSCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H[1]
💡 Explicación en Lenguaje Sencillo (ELI5)

Imagina a un empleado que recibe una frase cuya puntuación puede cambiar la tarea: un signo puede convertir una instrucción de entrega en una segunda orden. Langflow enviaba el comando configurado a un shell que interpreta esa sintaxis como control, en vez de tratar el ejecutable y los argumentos como datos separados. La corrección valida el comando permitido e inicia el programa directamente, sin shell.[1], [2]

Conceptos Clave y Términos

Transporte MCP stdio
Inicia un servidor MCP como proceso hijo local e intercambia mensajes por la entrada y salida estándar.[1], [2]
Inyección de comandos (CWE-78)
Texto influido externamente altera el comando del sistema operativo enviado al shell o al lanzador de procesos.[1], [5]
Punto de ejecución
Ruta final que crea un proceso; la validación debe aplicarse aquí aunque existan controles previos en la API.[1], [2]
Configuración incrustada de flow/tweak
Configuración MCP incluida en un flow o una modificación de ejecución, no creada mediante la API de ajustes.[1], [2]

Mapeos de marcos

  • Referencia CWE para la debilidad descrita en esta guía: CWE-78

Análisis de Causa Raíz

Antes de la versión 1.10.3, la configuración MCP stdio unía el comando y sus argumentos en una cadena y ejecutaba bash -c con ella. La API de configuración obtuvo una lista permitida y controles de argumentos y entorno en la versión 1.9.0, pero las configuraciones MCP Tools incrustadas en flujos o tweaks podían eludir la validación del modelo porque el punto de ejecución no aplicaba una política común. Langflow 1.10.3 centraliza la validación en lfx.base.mcp.security.validate_mcp_stdio_config, la aplica a la API, flujos, tweaks, el componente heredado y justo antes de crear el proceso, y elimina el shell intermedio. CVE-2026-105697 es CWE-78, CVSS 3.1 9.9. Con el inicio de sesión automático desactivado, sigue haciendo falta un usuario autenticado que no sea administrador y pueda configurar o ejecutar la ruta MCP; el inicio automático predeterminado puede dejar instancias de desarrollo expuestas sin credenciales.[1], [2], [4], [5]

Flujo de Ataque Paso a Paso

Paso 1

El usuario alcanza una ruta de configuración MCP

El aviso describe el acceso mediante los ajustes del servidor MCP o un flow que utiliza el componente MCP Tools. En una instancia expuesta con el valor predeterminado de desarrollo LANGFLOW_AUTO_LOGIN=true, un atacante podía obtener un token sin credenciales. Con el inicio automático desactivado, aún podía bastar un usuario autenticado que no fuera administrador.[1]

Paso 2

La configuración llega a la preparación del proceso

El comando y los argumentos forman command_str mientras Langflow prepara una conexión MCP stdio.[1]

Paso 3

El shell interpreta la cadena

Antes de 1.10.3, la ruta usaba bash -c; la ejecución ocurría al intentar conectar, antes de completar el handshake MCP.[1]

Paso 4

Las comprobaciones de entrada son incompletas

La versión 1.9.0 valida los ajustes REST, pero los flow y tweaks pueden eludir esa validación del modelo.[1]

Paso 5

El proceso del host usa los privilegios de Langflow

El comando se ejecuta como usuario del servicio Langflow. La interfaz aún puede indicar que el servidor MCP no se inició.[1]

Paso 6

1.10.3 cierra el límite de ejecución

Una política común valida cada entrada y el instante previo al inicio del proceso; el programa se ejecuta sin shell.[1], [2]

Código Fuente: Vulnerable vs. Seguro

El fragmento vulnerable muestra el patrón de inicio mediante shell documentado en el aviso; no es un exploit ejecutable. El fragmento corregido resume el diseño de 1.10.3: una política común valida la configuración en cada entrada y de nuevo justo antes de crear el proceso, mientras la API recibe el ejecutable y los argumentos por separado. El inicio directo elimina la interpretación del shell, pero no hace que todo ejecutable o paquete permitido sea seguro por sí solo; los operadores también deben aplicar controles de origen de paquetes y aislamiento adecuados.[1], [2]

Fragmento de origen: lfx/base/mcp/util.py — fragmentos de código específicos

IMPLEMENTACIÓN VULNERABLE
# Forma de inicio afectada según el aviso (fragmento específico):
server_params = StdioServerParameters(
    command="bash",
    args=["-c", f"exec {command_str}"],
    env=env_data,
)
PARCHE SEGURO Y ROBUSTO
# Reducción basada en el código de 1.10.3: valida la política y crea el proceso directamente.
command_parts = shlex.split(command_str)
if not command_parts:
    raise ValueError("MCP stdio command is required")
command, args = command_parts[0], command_parts[1:]
validate_mcp_stdio_config(command, args, env_data)  # Repeat at the execution boundary.
server_params = StdioServerParameters(
    command=command,
    args=args,
    env=env_data,
)  # No shell wrapper. The shared validator rejects disallowed configurations.

Lista de Verificación de Seguridad para Ingeniería

Fuentes