Una ilustración abstracta generada sobre un fondo azul marino profundo. Una amplia estructura de puente de color pizarra abarca todo el encuadre, y una portilla rectangular en su cara izquierda permanece abierta y resplandece en ámbar. A través de esa abertura, un flujo de pequeños bloques idénticos se derrama hacia afuera sobre una tenue cuadrícula de plano, cruzando un delgado límite punteado de color cian dibujado en el primer plano sin ser detenido. En la parte inferior derecha, los bloques alimentan una baja retícula translúcida de nodos conectados que se asemeja a un almacén de memoria. No aparecen texto, letras, números, personas, marcas comerciales ni logotipos de organizaciones. El logotipo de OrcaRouter está integrado en la esquina inferior derecha de una franja blanca situada debajo de la ilustración.
AI Safety Incidents

RufRoot: una sola solicitud no autenticada al puente MCP de Ruflo ejecutó comandos, robó claves y envenenó la memoria de la IA

Autor

Rowan Sterling

Fecha de publicación

Últimos modelos · 20Ver todos los modelos →
Benchmarks: Artificial Analysis · actualizado a diario
Volver a todas las publicaciones

El 30 de junio de 2026, Noma Labs entregó al mantenedor de Ruflo un exploit funcional contra el propio proyecto. El equipo de investigación de Noma Security había descubierto que Ruflo — una plataforma de orquestación de agentes de código abierto publicada anteriormente como Claude Flow — incluía un despliegue predeterminado de Docker Compose que vinculaba su puente del Model Context Protocol al puerto 3001 en todas las interfaces de red y no solicitaba autenticación alguna. Una sola solicitud HTTP al endpoint /mcp bastaba para ejecutar comandos de shell dentro del contenedor como el node usuario, y desde esa shell un atacante podía leer todas las claves de API de proveedores de LLM en el entorno, volcar todas las conversaciones almacenadas, generar enjambres de agentes con cargo a las claves de la víctima y escribir instrucciones en AgentDB, el almacén de aprendizaje que seguiría orientando las respuestas de la IA para todos los usuarios de esa instancia. La falla es CVE-2026-59726, apodada RufRoot, con una puntuación de CVSS 10.0 y corregida en 3.16.3 en un plazo de 24 horas. Ninguna de las fuentes que hemos leído informa que se haya explotado en la naturaleza. El propio registro del archivo para esta falla, con su lista de fuentes y su grado de confianza, se encuentra en el archivo de incidentes de IA, junto a las otras entradas de MCP e infraestructura registradas a su alrededor.

El incumplimiento que abrió la puerta

Ruflo es lo que Noma Labs denomina un meta-harness de agentes: una capa autoalojada para enjambres de hasta 100 agentes, diseñada para Claude Code y OpenAI Codex, con memoria a largo plazo y un servidor MCP integrado para la invocación de herramientas. La configuración habitual es la que describe Noma: clonar el repositorio, añadir claves API de LLM, ejecutar docker compose up -d. El archivo compose predeterminado del proyecto vinculaba el puente a 0.0.0.0 en el puerto 3001 y vinculaba su MongoDB acompañante a todas las interfaces en 27017, con la autenticación de Mongo desactivada. Hasta dónde llega eso depende del firewall, del grupo de seguridad y de la segmentación de red en torno al despliegue; la propia formulación de Noma es que cualquier instancia accesible por red era totalmente explotable sin autenticación.

El MCP Bridge es un servidor Express.js que convierte las solicitudes JSON-RPC que llegan por HTTP en llamadas contra la biblioteca de herramientas interna de Ruflo. En la línea vulnerable, esa biblioteca contenía 233 herramientas que abarcaban acceso al shell, operaciones de bases de datos, gestión de agentes y almacenamiento en memoria. El análisis de Noma es directo sobre lo que eso significa: «El MCP Bridge no es una interfaz de depuración auxiliar aleatoria; más bien, es el sistema nervioso central de Ruflo. Cada llamada a herramienta, cada acción de agente, cada operación de memoria pasa por el MCP Bridge».

La capa de autenticación faltaba; no era meramente débil. POST /mcp y POST /mcp/:group implementan el protocolo JSON-RPC de MCP y pasan las solicitudes entrantes de tools/call directamente a la función interna executeTool(). Ruflo sí mantenía una lista de bloqueo de comandos, AUTOPILOT_BLOCKED_PATTERNS, destinada a detener operaciones peligrosas de shell, pero el aviso de GitHub es explícito en que «solo se aplicaba en el flujo de autopilot. POST /mcp y POST /mcp/:group lo eludían». Una llamada no autenticada que nombraba ruflo__terminal_execute ejecutaba, por lo tanto, comandos arbitrarios como el usuario node del contenedor, registrado en el aviso como uid 1000, sin necesidad de token, sesión ni interacción previa. No se necesitó escalada de privilegios para lo que vino después: las credenciales, las API de agentes, el almacén de memoria y la base de datos eran todas accesibles desde ese shell.

La cadena, en ocho pasos

Noma Labs publicó una prueba de concepto de ocho pasos y confirmó cada paso en vivo contra una implementación predeterminada de Ruflo en AWS EC2, usando devoluciones de llamada fuera de banda a Burp Collaborator para verificar la ejecución y la exfiltración. Los pasos no son consecuencias especulativas apiladas sobre un error teórico; son una secuencia demostrada, y la sección de remediación del aviso está escrita para operadores que ya podrían estar dentro de ella.

A hand-built HTML card headed 'The RufRoot chain, step by step', kicker 'RufRoot - CVE-2026-59726', subtitle 'Eight steps Noma Labs confirmed live against a default Ruflo deployment on AWS EC2'. Eight rows, each with a circled step number, the action, and what it yielded. 1, call tools/list: enumerate the 233 exposed tools. 2, call ruflo__terminal_execute over POST /mcp: shell inside the bridge container as node, uid 1000, verified by an out-of-band callback. 3, run printenv: every LLM provider API key in the container environment. 4, call ruflo__swarm_init and ruflo__agent_spawn: attacker-controlled agent swarms running on the victim's keys and compute. 5, call ruflo__agentdb_pattern-store: a fabricated SOC2 policy in the learning store, steering future output for all users. 6, query MongoDB on port 27017: every stored conversation, title and metadata. 7, write /app/beacon.js and inject it into index.js, then kill PID 1: a backdoor that survives the container restart policy. 8, clear shell history: no forensic trace. A footer cites Noma Labs and CVE-2026-59726, and marks step 5 as the step a patched redeploy does not undo.

El reconocimiento va primero porque la lista de herramientas es pública para cualquier invocador: tools/list devuelve las 233 entradas sin credencial. La ejecución de comandos se deriva del mismo endpoint, y la prueba de concepto de Noma lo confirmó con una devolución de llamada fuera de banda en lugar de inferirlo a partir del cuerpo de una respuesta. El paso del entorno es el que convierte el compromiso de un host en un problema de facturación y pérdida de datos: el archivo compose pasaba las claves del proveedor al contenedor y los procesos backend heredaban todo el entorno mediante { ...process.env }, de modo que un solo printenv los volcaba. Esas claves permitieron entonces que ruflo__swarm_init y ruflo__agent_spawn iniciaran enjambres controlados por el atacante que consumían la cuota y la capacidad de cómputo de la víctima.

El paso cinco es el que sobrevive a la intrusión. Usando ruflo__agentdb_pattern-store, Noma plantó una política de cumplimiento SOC2 fabricada que indicaba a la IA que incorporara una URL controlada por el atacante en cada script de despliegue que generara posteriormente. Dado que AgentDB existe precisamente para persistir este tipo de patrón de modo que el comportamiento de los agentes mejore entre sesiones, la entrada inyectada se comportó tal como el sistema estaba diseñado para hacerlo. «Las conversaciones futuras producen resultados influenciados por el atacante, y el usuario no tiene forma de saberlo», afirma el informe de Noma. Dark Reading, que informó sobre el fallo el 29 de julio, consultó a un experto externo sobre la distinción: John Gallagher, vicepresidente de Viakoo, lo calificó como una clase distinta de problema: «Esto no es explotar fallos de software, es envenenamiento de memoria».

Los pasos restantes son post-explotación convencional, ejecutados con una facilidad inusual. MongoDB en la red interna de Docker no tenía autenticación, por lo que los atacantes instalaron un cliente en /tmp, volcaron conversaciones y las enviaron fuera. La persistencia se logró escribiendo /app/beacon.js, agregando una require('./beacon.js') línea a index.js y matando el PID 1, después de lo cual la política de reinicio de Docker volvió a levantar el contenedor con el beacon activo. El paso final fue borrar el historial del shell. Todo ello se derivó de una única solicitud no autenticada; nada en el despliegue predeterminado detuvo la cadena en ningún momento.

La corrección, y la parte que un parche no puede alcanzar

El mantenedor publicó Ruflo 3.16.3 en las 24 horas siguientes a la divulgación del 30 de junio, y GitHub publicó el aviso GHSA-c4hm-4h84-2cf3 el 1 de julio de 2026. La remediación, registrada en el repositorio como ADR-166 y fusionada en la solicitud de extracción 2521, cambia los valores predeterminados en lugar de limitarse a añadir una comprobación:

• El puente MCP se enlaza a 127.0.0.1 de forma predeterminada; un enlace público requiere MCP_AUTH_TOKEN, y el proceso termina con un mensaje fatal al arrancar si el token no está presente.

• El middleware de token Bearer con comparación en tiempo constante se sitúa delante del puente.

• terminal_execute está restringido del lado del servidor detrás de MCP_ENABLE_TERMINAL=true, desactivado por defecto, y la restricción se aplica de forma idéntica en /mcp, /mcp/:group y el flujo de piloto automático — el eslabón faltante que había permitido que la cadena revelada llegara a un shell.

• MongoDB requiere autenticación, y se necesita una contraseña de root para que el contenedor arranque.

• El contenedor del puente se ejecuta con un sistema de archivos raíz de solo lectura con tmpfs, una lista de permitidos CORS sustituye el comodín, y los bloqueos de regresión de CI cubren la configuración estática y el comportamiento en tiempo de ejecución.

Nada de eso elimina una entrada ya escrita en AgentDB. El aviso indica a los operadores de cualquier instancia expuesta que bloqueen de inmediato en el firewall los puertos 3001 y 27017, roten las claves del proveedor, auditen el almacén de patrones en busca de entradas inyectadas agentdb_pattern-store y las purguen, auditen MongoDB en busca de manipulación y reconstruyan los contenedores a partir de imágenes limpias. Su advertencia es inusualmente directa: «Un nuevo despliegue parcheado por sí solo NO revierte el envenenamiento». El informe de Noma llega a la misma conclusión: auditar el almacén de patrones forma parte de la remediación, y el parche no forma parte de ella.

La razón es estructural y no fruto de descuido. Un almacén de patrones que moldea la salida futura del modelo no tiene forma de distinguir una instrucción legítima aprendida de una plantada por un atacante; ambas llegan como patrones, y el sistema está construido para confiar en ellos. Eso convierte una vulnerabilidad de red en un problema de integridad de datos con una acumulación desconocida, y significa que la pregunta para un operador no es solo si el puerto era accesible, sino qué contiene la memoria ahora.

A hand-built HTML timeline card headed 'From disclosure to coverage', kicker 'RufRoot - disclosure timeline', subtitle 'Five dates, from the private report to the day the record was filed'. Six dated rows. 30 June 2026: Noma Labs discloses the flaw to Ruflo's maintainer with a working proof of concept. 1 July 2026: Ruflo 3.16.3 ships and GHSA-c4hm-4h84-2cf3 is published with CVSS 10.0. 9 July 2026: the CVE record for CVE-2026-59726 is published in the National Vulnerability Database, later marked Deferred. 29 July 2026: The Hacker News and Dark Reading report the flaw; Noma Labs publishes its research. 30 July 2026: SecurityWeek reports it, and the record is dated to this day. A separate amber note reads: no source we read reports exploitation in the wild at any point on this timeline. A footer cites The Hacker News, the GitHub advisory API, the NVD record and SecurityWeek.

Qué está establecido y qué no

El registro técnico aquí es primario y coherente. El aviso nombra el paquete afectado (npm ruflo anterior a 3.16.3), la versión parcheada, los endpoints exactos, el usuario del contenedor y los dos puertos; las notas de la versión del mantenedor describen la misma cadena; el escrito de Noma proporciona el detalle de la prueba de concepto; y medios independientes — The Hacker News y Dark Reading el 29 de julio de 2026, SecurityWeek el 30 de julio — informan del mismo mecanismo sin añadir detalles contradictorios. Una nota de investigación de Cloud Security Alliance fechada 5 de agosto de 2026 reafirma la secuencia y la sitúa junto a anteriores fallos no autenticados de MCP y de orquestación de agentes que había seguido. El archivo califica la confianza del registro como A, indiscutida, y lo marca como un hito; su calificación de gravedad para el registro es alta, distinta de la propia puntuación CVSS.

Un detalle de puntuación merece exponerse con precisión, porque dos documentos primarios no coinciden. GHSA-c4hm-4h84-2cf3 lleva CVSS 10.0 en el vector AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H — el cambio de alcance es lo que lo lleva al máximo. La copia del mismo aviso en la página de la versión 3.16.3 describe la puntuación como "CVSS 9.8 crítica". El registro de la National Vulnerability Database, consultado el 30 de octubre de 2026, publicado el 9 de julio de 2026 y marcado como Diferido, incluye el 10.0 de GitHub como métrica secundaria y ninguna puntuación propia elaborada por la NVD. No encontramos una explicación para la línea del 9.8, y este artículo no la resuelve.

Las cifras de adopción son más débiles. Noma Labs describió el proyecto en ese momento como uno con más de 67.000 estrellas en GitHub, aproximadamente 10 millones de descargas y alrededor de 1 millón de usuarios activos; The Hacker News, tal como lo resumió Cloud Security Alliance, citó más de 66.500 estrellas. Los recuentos de descargas y usuarios son de Noma y no están verificados de forma independiente. El recuento de estrellas del repositorio a 30 de octubre de 2026 era de 80.198 —una comprobación del alcance del proyecto, no una medida de exposición, y ninguna fuente ha publicado cuántas implementaciones eran realmente accesibles desde una red.

A hand-built HTML card headed 'Established, and not', kicker 'RufRoot - evidence', subtitle 'What the advisory, the release notes and the research support, against what nobody has shown'. Two columns. The left column, headed 'Established', lists: CVE-2026-59726 affects npm ruflo below 3.16.3 and is patched in 3.16.3; the default compose file bound the MCP bridge to 0.0.0.0 on port 3001 and MongoDB to 27017 without authentication; POST /mcp and POST /mcp/:group reached 233 tools and terminal_execute with no credential, running as node, uid 1000; Noma Labs confirmed an eight-step chain live on AWS EC2 with out-of-band callbacks, including an AgentDB pattern injection; the advisory was published 1 July 2026 with CVSS 10.0 and the fix shipped within 24 hours of the 30 June disclosure; the archive record is confidence A, undisputed, no real harm recorded, GLOBAL, MCP and INFRA. The right column, headed 'Not established', lists: that anyone exploited the flaw in the wild; how many Ruflo deployments were actually network-reachable; that any instance's AgentDB was poisoned, since no audit results are published; whether 9.8 in the release notes or 10.0 in the advisory is the intended score; Noma's counts of 10M downloads and 1M active users, which no independent source confirms; that any operator received notice beyond the public advisory. A footer cites GHSA-c4hm-4h84-2cf3, the Ruflo 3.16.3 release notes, Noma Labs and SecurityWeek.

Lo que no está establecido es la parte que más fácilmente se infla. Ni Noma, ni el mantenedor ni ningún medio que hayamos leído afirma que la falla se haya explotado en el mundo real, y el archivo no registra ningún daño real para esta entrada. La prueba de concepto de Noma se ejecutó contra una implementación que los investigadores controlaban en EC2, lo que muestra lo que permite una instalación predeterminada, no lo que sufrió ninguna instancia de producción en particular. No se ha publicado ningún recuento de implementaciones de Ruflo expuestas a internet, y ningún operador ha publicado los resultados de una auditoría de AgentDB, por lo que tanto la población afectada como la cantidad de memoria envenenada existente son desconocidas. El consejo de Cloud Security Alliance de tratar las implementaciones expuestas como compromisos totales es una postura de riesgo justificada por la explotación sin interacción; no es evidencia de que se haya producido una brecha.

Por qué el archivo lo marca como un hito

La marca emblemática del archivo se basa en algo más específico que una puntuación máxima. Una vulnerabilidad de ejecución remota de código con CVSS 10.0 en un popular servicio autoalojado es un género conocido, y la corrección aquí llegó en un plazo de 24 horas. Lo que distingue a RufRoot es que el exploit terminó en el propio pipeline de aprendizaje de la IA, donde la solución convencional —actualizar, volver a desplegar, cerrar el puerto— deja la instrucción inyectada en su lugar y sigue moldeando las respuestas. La nota de Cloud Security Alliance lo interpreta como un caso de estudio de un patrón que ya había documentado en herramientas de agentes, entre las que se incluyen una cadena de checkpoints de LangGraph y una superficie de AutoGen Studio no autenticada, y sostiene que la memoria persistente utilizada para moldear el comportamiento de los agentes debería tratarse como un almacén de datos sensibles bajo monitoreo de integridad, en lugar de como una caché.

Esa reformulación es la conclusión práctica. El artefacto visible de este incidente es una dependencia parcheada y un aviso publicado; el invisible es cualquier patrón que la AgentDB de un operador aún pueda contener, y no existe ninguna herramienta ni firma publicada que distinga una política aprendida legítima de una implantada. Para las organizaciones que ejecutaron el archivo compose predeterminado detrás de una red accesible, la respuesta útil es la que tanto Noma como el aviso ofrecen: asumir que las claves fueron leídas, rotarlas e inspeccionar la memoria antes de confiar en las respuestas que produce.