Ilustración técnica abstracta sobre un fondo azul marino oscuro: un chasis translúcido sostiene una pila de pequeños paneles redondeados, y un único canal oscuro sin etiqueta desciende desde la parte inferior de esa pila directamente a través del suelo del chasis hasta un compartimento inferior sin iluminación. Junto al canal, tres pequeñas compuertas pálidas permanecen cerradas sobre un estante, mientras que el propio canal pasa entre ellas sin ninguna compuerta en su recorrido. Una fina línea ámbar entra en el chasis desde la izquierda y desaparece en la pila. Sin texto, sin personas, sin logotipos de organizaciones, sin representación literal de ningún sistema real.
AI Safety Incidents

MaxKB adjuntó una herramienta de shell a cada asistente con herramientas habilitadas y nunca la restringió

Autor

Alistair Wren

Fecha de publicación

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

MaxKB, una plataforma de asistente empresarial de código abierto publicada bajo la organización de GitHub 1Panel-dev, construyó sus agentes de chat sobre un marco de trabajo que añade silenciosamente una herramienta de shell siempre que se pasa un backend con capacidad de shell — y MaxKB nunca eliminó la herramienta ni pidió a nadie que aprobara su uso. La vulnerabilidad es CVE-2026-77521, publicada como aviso de GitHub GHSA-f36j-f34j-h3rx el 2 de septiembre de 2026 y puntuada con 10,0 sobre 10 según CVSS 3.1 para el caso de un asistente público o integrado. Lasso Security, que la encontró y la reportó, demostró que un mensaje de chat — o el texto que el asistente simplemente ingiere mediante recuperación o un documento subido — podía inducir al modelo a ejecutar comandos: en una implementación sobre hardware físico directamente en el host, y en el contenedor oficial a través de un envoltorio que, según los investigadores, se puede eludir con un punto y coma. Ninguna fuente citada registra que la vulnerabilidad se haya explotado en el mundo real. La calificación de gravedad, la evaluación de confianza y la lista de fuentes del propio registro se encuentran en el archivo de incidentes de IA, junto con las entradas vecinas de MaxKB y de herramientas para agentes del mismo lote de divulgación.

MaxKB es un producto autoalojado para crear asistentes aumentados por recuperación: un operador crea un asistente, le adjunta capacidades —herramientas, servidores de Model Context Protocol, habilidades, subaplicaciones—, conecta una base de conocimiento construida a partir de documentos cargados o sitios web rastreados y, después, expone el asistente bien mediante una consola autenticada, bien como un widget de chat público e integrable. Esa versatilidad constituye la exposición. La condición de activación del aviso no es una configuración inusual, sino la ordinaria: cualquier asistente con al menos una capacidad adjunta enruta su chat a través de la ruta del agente afectada, mientras que un chat sin capacidades adjuntas no lo hace. El artículo de Lasso describe el proyecto como uno de los más ampliamente adoptados de su categoría y señala que MaxKB normalmente se despliega como un servicio multinquilino —lo que sitúa un comando que se ejecuta como el usuario de la aplicación por debajo del modelo de multinquilino, en lugar de dentro de la porción correspondiente a un solo inquilino.

La herramienta de shell llegó con el framework, no con el producto

MaxKB crea estos agentes con la biblioteca deepagents de LangChain, fijada a la versión 0.6.11 en el pyproject.toml del proyecto tanto en la etiqueta vulnerable como en la actual. En apps/application/flow/tools.py, en la línea 467 de la etiqueta v2.10.3-lts, el proyecto llama a create_deep_agent con backend establecido en SandboxShellBackend, una subclase de MaxKB que ejecuta comandos en el host. Según el aviso, deepagents inyecta automáticamente un conjunto de herramientas siempre que se pase un backend de shell de esa manera: execute, ls, read_file, write_file, edit_file, glob y grep. No forman parte del argumento tools=list, que solo contiene las herramientas propias del operador, las herramientas MCP y las herramientas de habilidades. No se pueden eliminar de la interfaz ni mediante configuración.

MaxKB tampoco pasa excluded_tools, el argumento de la librería que las eliminaría. El aviso es cuidadoso al explicar por qué eso importa incluso como remedio: excluded_tools "elimina la herramienta de lo que se le indica al modelo, no del ejecutor". La distinción entre una herramienta de la que el modelo no es consciente y una herramienta que no puede ejecutarse es todo este error en miniatura.

Una puerta que enumera tres herramientas y omite la cuarta

El control human-in-the-loop en esa misma llamada es una sola línea y enumera tres operaciones: interrupt_on={"write_file": False, "read_file": False, "edit_file": False}. Se nombran escribir un archivo, leer un archivo y editar un archivo. La ejecución de comandos no es una clave del diccionario en absoluto. Según la lectura del aviso, eso significa que no se solicita aprobación para execute —las tres operaciones del sistema de archivos se nombran y se configuran explícitamente para no interrumpir, y la herramienta de shell no se nombra en absoluto.

En conjunto, la ruta es: el texto no confiable llega al modelo, el modelo llama a execute y el comando se ejecuta. La advertencia señala dos formas en las que puede llegar el texto no confiable. La directa es el chat: un widget público o incrustado, o la conversación de otro inquilino. La indirecta es el contenido que ingiere el asistente: un documento RAG, un archivo subido o una página web que la plataforma rastrea e incorpora a una base de conocimiento. La publicación de Lasso concreta la segunda ruta, al observar que «el conjunto de personas que pueden poner texto delante del modelo es mayor que el conjunto de personas que pueden chatear con él».

En una instalación bare-metal, el comando es solo un comando

Todo lo que MaxKB hace en materia de contención ocurre en apps/application/flow/backend/sandbox_shell.py, y en v2.10.3-lts comienza con un valor predeterminado. La línea 9 dice _enable_sandbox = bool(int(CONFIG.get("SANDBOX", 0))), y SANDBOX no aparece en Config.defaults en apps/maxkb/conf.py. A falta de una configuración explícita de MAXKB_SANDBOX, el valor es cero, se omite la rama del wrapper de la línea 65, y execute llega a subprocess.run con shell=True directamente en el host, como el usuario que ejecuta el servicio —root, según la formulación del aviso, si el servicio se ejecuta como root.

Esa es la configuración que los investigadores utilizaron para su prueba de concepto en el host. Ejecutaron el código real de MaxKB desde el código fuente con MAXKB_SANDBOX sin definir, crearon un asistente con una herramienta adjunta y le pidieron, en un único mensaje de chat, que ejecutara comandos de información del sistema. La herramienta de ejecución se activó y escribió un archivo cuyo contenido era la propia salida de uname, id y sw_vers del host — una salida que, según señala el aviso, se confirmó ausente dentro de cualquier contenedor. Lasso también registra el límite de lo que lo detuvo: el modelo rechazó un archivo de prueba con un nombre descaradamente evidente, mientras que no rechazó una formulación operativa benigna. La alineación del modelo, en sus palabras, es «un freno parcial, no un control».

En la imagen oficial, el sandbox se ejecutó y aun así filtró.

El contenedor oficial establece MAXKB_SANDBOX=1 en la imagen base, en installer/Dockerfile-base, línea 48, así que el wrapper está activo allí — y el wrapper es el segundo defecto. Construía una sola cadena: env -i LD_PRELOAD=/opt/maxkb-app/sandbox/lib/sandbox.so seguido de gosu sandbox y luego el comando proporcionado por el modelo, entregada a un shell que se ejecutaba como root. Como el comando se interpolaba como texto, solo su primer token quedaba bajo gosu. Cualquier punto y coma, tubería, redirección o sustitución de comandos en la salida del modelo era evaluada por el shell externo con privilegios de root antes de que el sandbox siquiera llegara a verla.

El análisis de Lasso describe la forma en que funciona: una carga útil de env -i LD_PRELOAD=... PATH="$PATH" gosu sandbox ls; whoami; id, en la que ls está confinado, whoami no lo está, y todo lo que sigue se ejecuta sin restricciones. Durante las pruebas, los investigadores escribieron un archivo propiedad de root con una redirección mientras el comando interno del sandbox estaba bloqueado. Agravando la situación, ni installer/Dockerfile ni installer/Dockerfile-base contienen una directiva USER, por lo que la imagen de la aplicación se ejecuta como UID 0; el aviso informa que se confirmó root en tiempo de ejecución. Por lo tanto, el contenedor ejecutaba comandos de todos modos, y el sandbox solo decidía cuáles se atribuían cosméticamente al usuario de bajos privilegios.

El flujo de ataque completo que describe Lasso no necesita ningún acceso al objetivo. El atacante coloca comandos en una página web, espera a que el agente de una víctima la rastree y la incorpore a una base de conocimiento, y luego la víctima hace una pregunta normal. La respuesta vuelve correcta y legítima; el curl inyectado ya se ha ejecutado contra el servidor del atacante. El aviso señala que los investigadores probaron solo sus propias implementaciones, no ninguna instancia de MaxKB de terceros ni alojada.

Lo que las fuentes establecen y lo que simplemente no se mide

El mecanismo, los dos modos de despliegue, el crédito y la versión corregida coinciden en cuatro documentos: el aviso de GitHub, el registro de la NVD publicado el 21 de septiembre de 2026, el propio análisis técnico de Lasso del 10 de septiembre de 2026 y el informe de GBHackers del 22 de septiembre de 2026, que es la única cobertura de un medio independiente encontrada para esta CVE. Ninguna fuente cuestiona ninguna parte del hallazgo, y el archivo registra la entrada como indiscutida en su grado de confianza más alto.

Lo que las fuentes no contienen es medida alguna de exposición. No hay un recuento de despliegues de MaxKB, ni un recuento de asistentes expuestos a internet o integrados, ni resultado de escaneo alguno, ni telemetría, ni una víctima identificada. Nada en el registro muestra que la falla se haya utilizado contra alguien, y la propia evaluación de explotación de CISA concuerda: el bloque SSVC adjunto al registro de NVD el 22 de septiembre de 2026 califica la explotación como "poc", lo automatizable como "yes" y el impacto técnico como "total". El modelo EPSS de FIRST situó la probabilidad de explotación en los próximos 30 días en 1,05 por ciento, el percentil 64, el 27 de octubre de 2026, y la CVE no aparece en el catálogo Known Exploited Vulnerabilities de CISA con fecha del 27 de octubre de 2026. La propia calificación del archivo refleja la misma evidencia: gravedad alta, daño real falso.

El 10.0 merece que se declare su alcance, porque es la cifra que más probabilidades tiene de citarse fuera de contexto. Es la puntuación para el caso del asistente público o embebido, donde el vector CVSS dice AV:N/AC:L/PR:N/UI:N/S:C — accesible por red, sin privilegios, sin interacción del usuario, con un cambio de alcance porque un comando dentro del asistente cruza al sistema operativo anfitrión. La puntuación es de la CNA, y la CNA aquí es el programa de avisos de GitHub, que es también hacia donde apunta el identificador de origen del registro CVE. NVD presenta el mismo vector como métrica secundaria y, a fecha de 28 de octubre de 2026, incluye la entrada en estado "Deferred", lo que significa que NVD ha publicado el análisis del asignador en lugar del suyo propio.

Rendered two-column card with the kicker 'MAXKB · CVE-2026-77521' and the title 'What the sources establish, and what they do not', subtitled with its sources: GHSA-f36j-f34j-h3rx of 2 September 2026, the NVD record of 21 September 2026, Lasso Security's write-up of 10 September 2026, GBHackers of 22 September 2026, FIRST EPSS, the CISA KEV catalogue and the repository tags. The left column, headed 'Established' in blue, lists eight items: CVSS 3.1 base score 10.0 with the vector AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H for a public or embedded assistant; CWE-78 OS command injection, CWE-250 unnecessary privileges and CWE-749 exposed dangerous method; deepagents 0.6.11 auto-adding execute to any shell backend, with no excluded_tools passed by MaxKB; the approval map covering write_file, read_file and edit_file with execute not a key in it; affected at or below 2.10.3-lts per the advisory and at or below 2.10.4-lts per Lasso Security's write-up; fixed in 2.10.5-lts, published 6 August 2026, 27 days before the advisory; the CISA SSVC assessment of 22 September 2026 with exploitation poc, automatable yes and technical impact total; and EPSS 1.05 percent at the 64th percentile on 27 October 2026 with no listing in the CISA KEV catalogue of that date. The right column, headed 'Not established, or not measured' in amber, lists seven items: no exploitation in the wild recorded by any cited source, with the archive recording real harm as false; no count of affected, exposed or internet-facing deployments; no named victim and no evidence of use in any intrusion; NVD status Deferred, so the 10.0 is the assigner's analysis rather than NVD's; disagreement between the two primary sources on the affected range boundary; the researchers' testing confined to their own deployments; and no detection or triage guidance for either deployment mode. A footer reads 'Card rendered by OrcaRouter. The 10.0 is scored for a public or embedded assistant; the archive grades the record high.' The OrcaRouter logo is composited in the bottom-right corner.

El parche se publicó un mes antes que el aviso.

La cronología avanza en sentido inverso desde la publicación, y es la parte menos intuitiva del registro. Lasso informó de la vulnerabilidad de forma privada a través del canal de avisos de GitHub el 8 de julio de 2026. MaxKB respondió al día siguiente, acotando el informe a la imagen oficial y solicitando una prueba de concepto en contenedor; los investigadores la aportaron, junto con la elusión del sandbox, el 10 de julio. Un commit de corrección, 594f50f2, se integró el 9 de julio —un día después del informe— y reescribió sandbox_shell.py para que primero se analice la cadena de comandos del modelo y el prefijo gosu se aplique a cada comando simple en lugar de solo al primero, volviendo a citar cada lista de argumentos para que la sustitución no pueda escapar al shell padre. El análisis de Lasso describe el cambio como la aplicación del prefijo gosu «a cada comando simple, no solo al primero».

La versión que lo incluía, v2.10.5-lts, se publicó el {{1}}6 de agosto de 2026{{/1}}. El aviso de GitHub se publicó el {{2}}2 de septiembre{{/2}}, NVD publicó la CVE el {{3}}21 de septiembre{{/3}}, se añadió el bloque SSVC de CISA y GBHackers informó el {{4}}22 de septiembre{{/4}}, y el propio artículo de Lasso apareció el {{5}}10 de septiembre{{/5}} — en medio de esa secuencia, no al principio. Un operador que seguía las etiquetas de lanzamiento en lugar de las fuentes de avisos tuvo el parche aproximadamente cuatro semanas antes de la advertencia.

El límite de versiones merece más atención de la que le presta el aviso, porque las dos fuentes principales no coinciden y el repositorio zanja la cuestión. El campo del formulario del aviso registra las versiones afectadas como «<= 2.10.3-lts», con una nota de que esto se verificó en 2.10.3-lts y de que la ruta vulnerable «probablemente» afecta a todas las versiones que construyen agentes de esta forma. El propio informe de Lasso indica que el rango afectado es «<= 2.10.4-lts». Las etiquetas confirman el rango más amplio: v2.10.4-lts, publicada el 16 de julio de 2026, contiene el mismo sandbox_shell.py de 75 líneas que v2.10.3-lts, y el archivo reescrito de 311 líneas aparece por primera vez en v2.10.5-lts. Un operador de 2.10.4-lts que solo hubiera leído el rango del aviso habría concluido que quedaba fuera de él. No era así.

Rendered vertical timeline card with the kicker 'MAXKB · CVE-2026-77521' and the title 'Reported, fixed, released, disclosed', subtitled that the dates come from Lasso Security's disclosure timeline, the repository's release tags and commit metadata, the NVD record and GBHackers, and that every date is a single day. Ten dated entries run down a single spine: 8 July 2026, reported privately to 1Panel-dev through GitHub's advisory channel; 9 July 2026, fix commit 594f50f2 rewrites sandbox_shell.py and the vendor asks for a container proof of concept; 10 July 2026, the container proof of concept and the sandbox bypass supplied; 16 July 2026, v2.10.4-lts released, still carrying the 75-line unpatched sandbox_shell.py; 6 August 2026, v2.10.5-lts, the fixed release with a 311-line wrapper and gosu applied to every simple command; 2 September 2026, advisory GHSA-f36j-f34j-h3rx published with CVSS 10.0; 10 September 2026, Lasso Security publishes MaxKBypass; 21 September 2026, NVD publishes CVE-2026-77521, with the CISA SSVC added the next day and GBHackers reporting; 15 October 2026, v2.10.7-lts flips the code default SANDBOX from 0 to 1; 22 October 2026, v2.10.8-lts still builds the agent with SandboxShellBackend and still omits execute. A dark band at the foot headed 'The gap' reads that the fixed release preceded the advisory by 27 days, that v2.10.4-lts was released a week after the fix commit and does not contain the fix, and that the execute tool has never been gated because the approval map at v2.10.8-lts still names only write_file, read_file and edit_file. A footer reads 'Card rendered by OrcaRouter.' The OrcaRouter logo is composited in the bottom-right corner.

Lo que el arreglo no hizo

Lo que corrige 2.10.5-lts es el wrapper: ya no construye una cadena de shell bajo root. Lo que no hace es nada respecto a la herramienta. La lectura directa del repositorio en la etiqueta v2.10.8-lts, publicada el 22 de octubre de 2026, muestra que el agente todavía se construye con backend=SandboxShellBackend y que interrupt_on todavía contiene exactamente tres claves —write_file, read_file y edit_file— sin execute. Las dos primeras sugerencias de remediación del aviso, construir sobre un backend de no ejecución por defecto y añadir "execute": True al mapa de aprobación, no están presentes en esa versión.

La recomendación de cierre seguro ante fallos llegó más tarde, en v2.10.7-lts, y es importante para el modo de despliegue que estaba en peor situación. Publicada el 15 de octubre de 2026, cambia la línea de sandbox_shell.py de CONFIG.get("SANDBOX", 0) a CONFIG.get("SANDBOX", 1). Una instalación desde código fuente o bare-metal que nunca definió la variable ahora tiene el wrapper activado por defecto en lugar de desactivado, lo que constituye la recomendación de «cerrar ante fallos en despliegues que no sean en contenedores» en sentido estricto. El aviso pedía más que eso bajo el mismo epígrafe —que el flujo con capacidad de ejecución se negara a iniciarse cuando el entorno de ejecución del sandbox no estuviera disponible— y pedía por separado que el wrapper nunca construyera una cadena de comandos para un shell de root. En el lado de los contenedores, un hecho y no una recomendación: ni installer/Dockerfile ni installer/Dockerfile-base incluyen una directiva USER en la etiqueta v2.10.8-lts, por lo que la imagen de la aplicación sigue iniciándose como root.

Leídos en conjunto, el estado del registro a 28 de octubre de 2026 es el siguiente. La segunda mitad de la vulnerabilidad —el sandbox del que se escapó un punto y coma— está cerrada, y el valor predeterminado fail-open en los despliegues de host está cerrado. La primera mitad, una herramienta execute que llega con un objeto de backend y no es una clave en el mapa de aprobación, sigue siendo la forma en que MaxKB construye un asistente con herramientas habilitadas. El propio consejo de remediación de los investigadores fue el limitado: actualizar a 2.10.5-lts o posterior y ejecutar la versión de Docker con el sandbox habilitado. GBHackers transmitió la misma instrucción además de una lista más amplia para administradores: deshabilitar los backends de agentes con capacidad de shell a menos que la ejecución de código sea explícitamente necesaria, exigir aprobación humana antes de cualquier acción execute, ejecutar los contenedores como no root y tratar las páginas rastreadas, los documentos RAG y los archivos subidos como entrada no confiable.

El otro registro de MaxKB del mismo lote de septiembre

La segunda entrada de MaxKB del archivo de este lote es un error diferente con un desenlace peor. CVE-2026-77516, también publicado en NVD el 21 de septiembre de 2026, es una omisión de permisos en lugar de una inyección de comandos: desde la versión 2.0.0 hasta la 2.9.2, un miembro del espacio de trabajo con el rol más bajo, a quien se le denegaba explícitamente el acceso a una herramienta mediante WorkspaceUserResourcePermission, aún podía vincular el identificador de esa herramienta mediante tool_ids, skill_tool_ids o mcp_tool_ids y ejecutarla a través de la ruta de despacho del agente o del flujo de trabajo. La ruta de despacho no vuelve a aplicar la concesión por herramienta que aplican las rutas dedicadas de herramientas, y la ejecución de la herramienta descifra init_params en el lado del servidor, por lo que el llamador recibe las credenciales que porta la herramienta a la que se le denegó el acceso. Su puntuación es 5.4, y la descripción de NVD termina con una frase que CVE-2026-77521 no tiene que incluir: «No hay una versión corregida disponible a la fecha de esta revisión.»

El contraste es la parte útil para cualquiera que esté evaluando el par. La falla que puntuó 10.0 tuvo una corrección confirmada en menos de un día y publicada un mes antes de que se divulgara. La falla que puntuó 5.4 no tenía ninguna versión corregida publicada en el momento de su CVE.

Abstract illustration on a dark navy field: a tall translucent shelf holds a row of small pale gate symbols, and a wide unbroken corridor runs beneath the shelf from left to right with nothing standing in it. At the corridor's midpoint a thin amber line drops down from the shelf above and joins the corridor floor, and a small cluster of glowing key-shaped tokens rests just past the join, out of reach of the gates. No text, no people, no organisation logos, no literal depiction of any real system.

Lo que sigue genuinamente abierto es más pequeño de lo que sugiere la puntuación y más grande de lo que implica una nota de parche. El hallazgo no está en disputa y el mecanismo fue verificado de extremo a extremo en ambos modos de despliegue por el equipo que lo encontró. La exposición está completamente sin medir —nadie ha publicado cuántos asistentes de MaxKB llevan una herramienta, cuántos de ellos son accesibles para una parte no confiable o cuántos se ejecutan en un host sin el sandbox—, así que la consecuencia real de la falla depende de hábitos de despliegue que ninguna fuente citada contabiliza. Y la parte del diseño que llevó la puntuación al máximo sigue presente en la versión actual: una capacidad que ejecuta comandos, incluida por defecto, ausente del mapa que consulta primero a una persona.