DevSecOps

CVE-2026-9198: la cadena de dos endpoints que entrega RCE completo en Langflow sin autenticación

El cuatro de agosto de 2026 la lista CISA KEV (Known Exploited Vulnerabilities) sumó una entrada que cualquier equipo que toque inteligencia artificial debería tener impresa en la pared: CVE-2026-9198, una vulnerabilidad de inyección de código en IBM Langflow OSS versiones 1.0.0 a 1.10.0 con CVSS 3.1 de 9.8. No es un 9.8 nominal — es un 9.8 operativo. Una instancia de Langflow con la configuración por defecto, expuesta a la red, se convierte en una máquina owned por cualquiera que sepa encadenar dos llamadas HTTP. No hay credenciales, no hay ingeniería social, no hay exploit sofisticado. Sólo dos endpoints y un exec().

Para entender por qué importa, hay que entender qué es Langflow y por qué tantas empresas lo tienen corriendo. Langflow es una plataforma OSS de código abierto para construir aplicaciones LLM visualmente, encadenando prompts, modelos, herramientas y memoria en un grafo que se ejecuta como un pipeline. Es, en esencia, el equivalente low-code de lo que antes hacías con LangChain a mano. Bajo el capó usa Python — y eso, como vamos a ver, es exactamente donde está el problema. IBM lo mantiene como proyecto OSS desde hace dos años y la adopción explotó en 2025 cuando los equipos empezaron a usarlo para prototipar agentes internos, RAG sobre documentación interna, y conectores a sistemas empresariales. Muchas de esas instalaciones quedaron corriendo en servidores de desarrollo, en Kubernetes de laboratorio, en instancias EC2 olvidadas — exactamente el tipo de superficie que DevSecOps pierde de vista porque no es código de producción. Pero lo es. Y CVE-2026-9198 lo demuestra.

La vulnerabilidad en sí es un estudio de caso de cómo dos decisiones de diseño aparentemente razonables se combinan para producir un desastre. La primera decisión está en /api/v1/auto_login. Este endpoint existe porque Langflow, durante el desarrollo local, necesita poder arrancar y autenticarse automáticamente sin que el desarrollador tenga que escribir credenciales a mano. Es un helper para la experiencia de desarrollo. El problema es que el endpoint no enforce autenticación, no está limitado a loopback (127.0.0.1), y emite tokens con rol SUPERUSER. Para cualquier llamante en la red. No para el usuario legítimo de esa máquina — para cualquier IP que sepa que el endpoint existe. La segunda decisión está en /api/v1/validate/code. Este endpoint existe para validar snippets de Python antes de que un usuario los guarde como nodo personalizado en su flujo. Es una feature útil: si escribes una función en el editor visual, Langflow la ejecuta en un entorno controlado para detectar errores de sintaxis y runtime antes de persistirla. Para validar, Langflow usa la función builtin exec() de Python sobre el código que recibe. Combinado con un token SUPERUSER obtenido gratis del endpoint anterior, exec() se convierte en un shell abierto al sistema operativo completo. Y como Langflow corre como servicio, ese shell corre con los privilegios del servicio.

La cadena de ataque es trivialmente reproducible. Paso uno: GET o POST a /api/v1/auto_login sin headers de autenticación, sin body, sin nada. Respuesta: un JSON con un token Bearer marcado como SUPERUSER. Paso dos: con ese token en mano, POST a /api/v1/validate/code con un body que contiene código Python arbitrario — el ejemplo canónico es un reverse shell con socket.connect y os.dup2, pero también funciona un simple subprocess.run(['whoami']) para validar que tienes ejecución. Respuesta: el código se ejecuta, y dependiendo del payload, el atacante obtiene una shell reversa, exfiltra datos, despliega un cryptominer, o pivotea hacia la red interna donde Langflow corre. El descubrimiento de IBM, publicado el diecisiete de julio, ya advertía que la PoC era funcional. El cuatro de agosto CISA lo confirmó: está siendo explotado en producción, contra instancias reales, en este momento.

El detalle que más debería preocupar a un CISO no es la técnica — es la decisión de producto que la hizo posible. /api/v1/auto_login no fue diseñado pensando en deployments de producción. Fue diseñado pensando en la experiencia del desarrollador que arranca Langflow en su laptop. Y esa es exactamente la zona gris donde DevSecOps pierde más activos: herramientas que nacieron para dev, que se adoptaron para prototipar, que se desplegaron para staging, que se quedaron en producción porque resolvían un problema real, y que nunca pasaron por un threat model serio. El equipo que mantiene Langflow tomó una decisión perfectamente razonable para un entorno local (autologin sin fricción) y la extendió implícitamente a un servicio de red. Esa es la lección. No necesitas una vulnerabilidad 0-day para que un atacante entre. Necesitas que un componente diseñado para confianza local sea accesible desde Internet sin controles.

Para los equipos que tienen Langflow corriendo, la primera pregunta es si tienen alguna versión entre 1.0.0 y 1.10.0 accesible desde red. Si la respuesta es sí, hay que asumir compromiso hasta que se demuestre lo contrario — esto es un 9.8 con KEV confirmado, no es el momento de correr un scanner y esperar el reporte. La mitigación inmediata es doble: actualizar a 1.10.1 o superior (el fix se liberó el veinticuatro de junio), y mientras tanto, bloquear acceso al endpoint /api/v1/auto_login en el ingress o en el WAF. Si Langflow corre detrás de un reverse proxy, una regla que devuelva 403 para /api/v1/auto_login a cualquier request que no venga de 127.0.0.1 rompe la cadena antes de que el atacante consiga el token. Si corre directo en un puerto, iptables o un NetworkPolicy de Kubernetes limitando el puerto a fuentes conocidas es la salida mínima viable.

Para detección, hay que mirar los logs de acceso de Langflow — y aquí está el segundo problema, porque muchas instalaciones OSS no loguean autenticación ni ejecución de código por defecto. Si tienes la versión vulnerable y no logueas, asumes que todo lo que pasó desde el cuatro de agosto fue observado por el atacante, no por ti. La señal mínima a buscar hacia adelante es cualquier request a /api/v1/validate/code precedido por un request a /api/v1/auto_login desde la misma IP en una ventana de cinco minutos. Cualquier request a /api/v1/validate/code que contenga palabras como import os, subprocess, socket, base64, o reverse shell strings en el body. Cualquier proceso hijo inesperado corriendo bajo el UID del servicio Langflow. En EDR, eso se traduce a alertas sobre exec() de Python invocando subprocess o network calls desde procesos Python que no son tu código.

El endurecimiento a mediano plazo es el mismo que aplicaría a cualquier AI toolchain expuesto a la red: cero confianza por defecto, autenticación obligatoria en todos los endpoints, segregación de red del plano de ejecución, y por sobre todo, threat modeling antes del deployment. Si tu equipo va a poner Langflow en producción, el threat model tiene que responder preguntas que el threat model de una app web tradicional no contempla: ¿qué pasa si un atacante consigue ejecutar código arbitrario en el intérprete Python del servicio? ¿qué datos sensibles son accesibles desde ese proceso? ¿qué redes internas puede alcanzar? Para Langflow específicamente, la respuesta a todas esas preguntas en una instalación por defecto es 'todo' — el proceso corre con acceso completo al filesystem del contenedor y a la red donde el contenedor está. Eso no es aceptable para producción sin aislamiento explícito.

La lección de fondo para DevSecOps es que la superficie de ataque se expandió sin que el modelo de amenaza la siguiera. Cada nueva herramienta de AI que adoptamos — Langflow, Flowise, n8n con nodos LLM, LiteLLM, VLLM, Ollama — es código Python que se conecta a la red y ejecuta prompts. Cada una con su propia lista de endpoints, su propia superficie de administración, sus propias decisiones de seguridad que tomó el equipo OSS que la mantiene. El radar de vulnerabilidades interno de una empresa promedio no cubre ese territorio porque no sabe que existe. El threat model no lo contempla porque el equipo que lo escribió pensó en términos de Kubernetes, de APIs REST, de microservicios — no en términos de runtimes de AI donde el código del usuario es el input principal. CVE-2026-9198 es la primera grieta visible en esa superficie. No va a ser la última.

Cronología del incidente y de la respuesta

El timeline que llevó a CVE-2026-9198 al KEV en menos de tres semanas desde disclosure es un acelerador de cómo está funcionando la cadena de disclosure en 2026 — para bien y para mal. Diecisiete de julio: IBM publica el advisory y libera Langflow 1.10.1 con el fix. Es un turnaround agresivo, lo que sugiere que IBM ya tenía presión interna o coordinación提前 con reporteros de seguridad. Veinticuatro de julio: primeros PoCs públicos empiezan a circular en repositorios de exploit research y en canales cerrados. Cuatro de agosto: CISA agrega el CVE al KEV con la fecha de due date para remediación fijada, lo que obliga a todas las agencias federales estadounidenses a parchear. Lo que no dice ese timeline oficial es todo lo que pasó entre el diecisiete y el cuatro de agosto: escaneos masivos de Internet buscando instancias de Langflow expuestas (Shodan reportó un pico de queries para el fingerprint de Langflow en esa ventana), primeros accesos no autorizados confirmados en honeypots operados por empresas de threat intel, y al menos dos campañas observadas que intentaron desplegar cryptominers XMRig a través de la cadena de RCE. La ventana entre disclosure público y exploit массivo es hoy, para una vulnerabilidad de AI toolchain, de días. No de semanas. No de meses.

Procedimiento de respuesta a incidentes si ya fue comprometido

Si tu equipo encuentra evidencia de explotación — un proceso hijo inesperado, un binario XMRig corriendo, tráfico de salida a un pool de minería, una sesión SSH reversa activa — el primer movimiento es contención, no análisis. Aísla la instancia de Langflow de la red sin matar el proceso (necesitas el artefacto para forense). Captura memoria del proceso Langflow si tienes tooling que lo soporte (AVML, LiME, o incluso un simple dd del /proc/PID/mem antes del kill). Captura el contenedor completo si corre en Kubernetes (kubectl debug + chroot, o crane export del image si puedes). Luego, sí, mata el proceso y bloquea el puerto. El análisis post-incidente se hace en una copia, no en el sistema activo que sigue comprometido. Las preguntas a responder en forense son: ¿desde cuándo? (logs de acceso, syscalls, mtime de los archivos tocados), ¿qué actor? (IPs origen, TTPs, IOCs compartidos por tu threat intel provider), ¿qué se llevó? (variables de entorno con posibles API keys, acceso a modelos LLM que pueden usarse para facturación o abuso, datos que el grafo Langflow procesó), ¿hacia dónde pivotó? (logs de red saliente, nuevas conexiones persistentes, túneles SSH reversos activos). El output de ese análisis no se queda en el equipo IR — se traduce a detections que se deployan en EDR, NDR, y SIEM para que la próxima instancia comprometida del mismo actor se detecte en minutos, no en días.

Consideraciones de supply chain: Langflow como dependencia

Hay un ángulo que el advisory oficial no cubre y que importa si tu empresa no corre Langflow directamente: lo usa como dependencia transitiva. Langflow importa docenas de paquetes Python, varios de los cuales tienen sus propios historiales de vulnerabilidades. Un análisis de SBOM de la versión 1.10.0 muestra cadenas de dependencias que llegan hasta FastAPI, Pydantic, Uvicorn, y httpx — todos con CVEs publicados en los últimos dieciocho meses. Si tu equipo consume Langflow como librería dentro de un producto más grande, o si lo embebes en un container image que después distribuyes, la superficie explotable no se limita al RCE directo. Un atacante que ya tiene ejecución puede abusar de las dependencias vulnerables para persistencia (modificar requirements.txt en runtime, plantar malware en site-packages), para movimiento lateral (explotar CVE en httpx para SSRF si está expuesto), o para escalar privilegios si el contenedor corre con capabilities innecesarias. Por eso la remediación correcta no es sólo upgrade a 1.10.1 — es regenerar el container image desde cero con SBOM actualizado, verificar firmas si usas cosign o sigstore, y auditar todas las imágenes base que se hayan construido a partir de la versión vulnerable. Las imágenes cached en registries internos pueden seguir sirviendo la versión vulnerable durante semanas si no se force un rebuild.

El patrón de diseño que produjo el bug y cómo detectarlo en otras herramientas

El patrón detrás de CVE-2026-9198 — un endpoint de conveniencia para desarrollo que no enforce controles en producción — se repite en docenas de herramientas OSS. Para detectarlo en tu propio inventario, las preguntas a hacer son tres. Primera: ¿la herramienta tiene un endpoint de auto-login, auto-registro, o bootstrap que funcione sin credenciales? Si sí, ¿está limitado a loopback o es accesible desde cualquier IP? Segunda: ¿la herramienta ejecuta código o scripts proporcionados por el usuario como parte de su funcionalidad normal? Si sí, ¿ese código corre en el mismo proceso que el servicio principal, o en un sandbox aislado? Tercera: ¿la documentación oficial de la herramienta habla de 'modo desarrollo' versus 'modo producción', y el modo producción es lo que se configura por defecto? Si la respuesta a cualquiera de las tres preguntas es la peligrosa, tienes una superficie que un atacante va a encontrar eventualmente. El bug de Langflow no fue un descuido menor — fue la consecuencia inevitable de un diseño que trataba al entorno de red con la misma confianza que al entorno local. Esa clase de decisión de diseño no es exclusiva de Langflow. Está en Flowise, en n8n cuando se configuran nodos Code, en JupyterHub con autenticación deshabilitada, en Airflow cuando se usa el Parameterized DAG Executor sin controles. La auditoría de AI toolchains en producción no puede hacerse con un checklist genérico — requiere entender el modelo de amenaza que cada herramienta asume y comparar contra el modelo de amenaza real del deployment.

Referencias técnicas: NVD CVE-2026-9198 (https://nvd.nist.gov/vuln/detail/CVE-2026-9198), CISA KEV catalog update 2026-08-04, IBM Security Bulletin para Langflow 1.10.1 publicado 2026-06-24, análisis técnico de VulnCheck sobre cadenas RCE en el AI stack, writeup de WhiteHat EU con PoC funcional, reporte de BleepingComputer sobre escaneos masivos post-disclosure. CVSS 3.1 vector: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H. CWE-94 Improper Control of Generation of Code. EPSS 17% al cierre de este artículo.