El interruptor estaba dentro del sandbox
La CVE-2026-82533, publicada el 8 de septiembre, es un 9,4 en DeepSeek Harness: el agente de codificación confinado podía apagar su propio sandbox con un solo comando de shell. El harness ejecutaba los comandos del agente en un sandbox del sistema operativo que restringía las escrituras de archivos, y exponía su plano de control como una interfaz HTTP en loopback, que el sandbox nunca cubrió. La comprobación que guardaba esa interfaz leía la cabecera Host que enviaba el llamante y nunca miraba de dónde venía la conexión. En Bromure Agentic Coding el agente ya está sin confinar dentro de la VM, y el plano de control al que tendría que llamar no existe en su lado de la línea.
Esta no necesitó ningún exploit. El agente confinado lanzó un comando de shell contra un puerto local, le pidió al sandbox que lo contenía que se apagara solo, y el sandbox aceptó.
DeepSeek Harness ejecuta los comandos de un agente de codificación dentro de un sandbox del sistema operativo. El sandbox es estrecho y deliberado: las escrituras de archivos se quedan dentro del workspace y de las carpetas temporales, y todo lo demás que haga el agente es problema de otro. La propia referencia de línea de comandos del proyecto lo dice. Con los ajustes por defecto, “las lecturas y el acceso a la red no están confinados”.
El harness también tiene una interfaz web. Corre en la misma máquina, en un puerto
HTTP local, y el harness le entrega su dirección al shell del agente para que las
herramientas puedan hablar con ella. Esa interfaz es el plano de control: guarda el
modo de una sesión, incluido el modo llamado danger-full-access, que apaga el
sandbox y detiene las peticiones de aprobación.
Los dos diseños son corrientes. Póngalos uno junto al otro y el agente puede apagar su propio sandbox con un comando, porque el sandbox nunca cubrió el loopback y el plano de control nunca comprobó quién llamaba.
Investigadores de OX lo encontraron. VulnCheck lo publicó el 8 de septiembre como CVE-2026-82533, CVSS 9,4. Funcionaba en una instalación por defecto, sin exposición de red y sin credenciales, hasta que DeepSeek publicó una corrección el 27 de agosto.
La comprobación que leía el sobre
La interfaz no tenía autenticación alguna. Lo que hacía sus veces era una función
llamada isTrustedApiRequest, y
DevOps.com cita lo que hacía:
“leía la cabecera de petición Host y permitía el acceso si el valor era una
autoridad de loopback o aparecía en una lista trustedHosts configurada”.
La cabecera Host es una línea de texto que escribe el cliente. Dice con qué
dirección cree el cliente que está hablando, y un llamante situado en cualquier
punto de la red puede teclear localhost ahí. El origen real de la conexión está
una capa más abajo, en la dirección del par TCP, y la comprobación de DeepSeek
nunca leyó ese valor. El registro de la CVE archiva el fallo bajo
CWE-345, Reliance on Untrusted
Inputs in a Security Decision.
El agente, sentado dentro de un sandbox que permitía llamadas de red, hizo una a la
interfaz y puso su propia sesión en danger-full-access con la aprobación en
never. Como
lo expresó The Hacker News,
el cambio de modo “no requería aprobación explícita porque modificaba ajustes de
sesión en lugar de solicitar permisos nuevos”.
El sistema de aprobación funcionó tal como fue diseñado. El agente nunca pidió hacer algo peligroso; pidió cambiar un ajuste, y ese ajuste gobernaba si las cosas peligrosas llegan siquiera a preguntarse. Una puerta de permisos inspecciona la operación que tiene delante. Esta petición era una escritura de configuración, y las escrituras de configuración no estaban en su lista.
La misma puerta, mirando al otro lado
Una interfaz que confía en una cabecera que envía el llamante no se preocupa por la
dirección desde la que llega la conexión. Si el puerto era alcanzable por red, la
misma llamada funcionaba desde fuera de la máquina: un desconocido sin autenticar
podía tomar el control del agente y exportar todas las conversaciones guardadas,
sin clave de API y sin gastar un solo token en una llamada al modelo. Por eso el
vector CVSS 4.0 abre con AV:N, y por eso el número es 9,4 y no algo local y
suave.
La cronología tiene un detalle que conviene guardar. Dos desarrolladores publicaron el hallazgo en el foro de discusiones de GitHub de DeepSeek el 13 y el 14 de agosto, por su cuenta, antes de que OX lo confirmara el 24 de agosto y antes de que existiera una CVE. El repositorio tenía más de 216.000 estrellas el 9 de septiembre y ningún archivo de política de seguridad que describiera cómo reportar una vulnerabilidad en privado, así que el único sitio que quedaba para ponerlo era un hilo público. La corrección, cuando llegó, fue autenticación: la herramienta ahora imprime un token de un solo uso en su dirección de arranque, el navegador cambia ese token por una cookie firmada, y toda llamada a la interfaz exige la cookie.
Si usted ejecuta este harness, revise la versión que hay en su máquina y no la
versión que publica el proyecto. Los envoltorios de escritorio de terceros traen su
propia copia. 0.1.2-alpha.1 solo estaba en GitHub el 27 de agosto,
0.1.2-alpha.2 el 30 de agosto fue la primera publicación en npm que llevaba la
corrección, y un envoltorio de Windows se quedó en 0.1.1-rc.2 hasta que pasó a
una compilación parcheada el 6 de septiembre.
Su harness también tiene uno de estos
Podría archivar esto como el fallo de un proyecto y seguir adelante. La forma viaja, porque a los harnesses de agentes les están brotando planos de control locales: un servidor de estado para el panel, un puente con el IDE, un endpoint MCP, una página en localhost que renderiza el diff. Cada uno es un pequeño servicio HTTP en su máquina, y el código que ejecuta su agente puede alcanzarlos todos, porque el agente corre en esa máquina y localhost es exactamente lo que significa “esa máquina”.
En cuanto un plano de control se sienta al lado de aquello que controla, una sola pregunta gobierna el desenlace: ¿puede la parte confinada direccionar los ajustes de su confinamiento? DeepSeek respondió que sí, mediante una comprobación que se creyó la palabra del llamante. Una comprobación más fuerte sigue respondiendo a una pregunta que nunca debió poder formularse. Una función de autenticación es código, el código tiene ramas de reserva, y este año ha sido un largo desfile de decisiones de seguridad fallando en la rama que nadie ejercitó.
Dónde vive el interruptor en un workspace Bromure
Bromure Agentic Coding empieza por el otro extremo. Un workspace Bromure deja al agente sin confinar.
Dentro del invitado el agente ya tiene lo que DeepSeek Harness llamaría
danger-full-access. Ese es el estado de reposo, por diseño. El manual lo dice: un
agente con inyección de prompt o que se porte mal “puede hacer lo que quiera
dentro del invitado, pero no puede leer una clave de API real, firmar con un
secreto de AWS real ni extraer una clave privada SSH: ninguna de esas cosas existe
en su lado de la línea”. El agente puede escribir donde quiera en el sistema de
archivos, ejecutar lo que quiera y abrir el puerto que quiera, así que no le queda
ningún modo al que escalar. La frontera es un borde de hipervisor, con el agente al
otro lado.
El invitado, por tanto, no tiene dirección alguna para el plano de control. La
política del workspace (guardrails, credenciales, reglas de firewall, servidores
MCP) vive en un profile.json bajo ~/Library/Application Support/BromureAC/profiles/
en su Mac, y usted la cambia en la ventana Edit workspace. El invitado no tiene ruta
de sistema de archivos hasta ese archivo ni ruta de red hasta el proceso que lo lee.
Los dos lados hablan por sockets virtio, puentes punto a punto entre anfitrión e
invitado que corren fuera de la red de la VM. Una VM de workspace tiene ocho, cada
uno con su trabajo: el 8443 lleva el HTTPS del invitado al proxy del anfitrión, el
8444 es el puente de ssh-agent, el 8445 alimenta el ayudante de credenciales de
AWS, el 5800 sirve el terminal y las rutas de archivos, el 5010 retransmite las
llamadas de retorno de OAuth. Cada uno sirve un protocolo fijo y ninguno acepta
cabecera Host, así que un llamante no tiene ninguna lista trustedHosts en la que
colarse hablando. En un vsock la identidad es topología: por qué puente llegaron los
bytes. Eso no se teclea en una petición.
Aprobaciones que no se pueden poner en never
La segunda mitad de danger-full-access apagaba los avisos, y esa mitad merece su
propia respuesta. Un agente que silencia sus propias aprobaciones es la parte que a
mí me quitaría el sueño.
En un workspace Bromure los avisos viven en el anfitrión. El proxy los levanta
después de que la petición ya ha salido de la VM, así que la sesión dentro del
invitado no lleva ningún ajuste capaz de suprimir uno. Preguntar antes de usar
detiene el primer uso de una credencial en una sesión y ofrece concesiones
limitadas en el tiempo: cinco minutos, una hora, el resto de la sesión o No
permitir. Una política de escritura puesta en Preguntar antes de escribir
detiene cada mutación con un diálogo encabezado
Allow write on "<scope>" from workspace "<name>"? que muestra la operación
literal, la propia sentencia SQL o METHOD /path para una llamada REST.
Permitir una vez no crea concesión alguna, así que la escritura siguiente
vuelve a preguntar. Las concesiones viven en memoria y se desvanecen cuando se
cierra la ventana de la sesión.
La página de guardrails enuncia la propiedad en una oración: una política de
escritura se “impone en el proxy, así que un agente comprometido en la VM no puede
saltársela”. El firewall de salida que hay debajo funciona igual: una tabla
ordenada de reglas con un control Unmatched traffic que puede poner en
Deny, aplicada dos veces, una en el switch virtual por IP de destino y nombre
de host espiado en el DNS, y otra en el proxy por nombre de servidor TLS y, para
las reglas web, por método HTTP. Las ediciones de reglas alcanzan a las sesiones
en curso sin reiniciar.
Una ejecución desatendida falla del lado seguro. Un workspace conducido sin
interfaz por SSH o por una automatización recibe las mismas cuatro opciones como
aviso de texto dentro de su tmux, y no responder significa denegar. El peor
desenlace ahí es una llamada bloqueada y una fila roja en la Security Timeline. En
esta CVE, el agente puso las aprobaciones en never y los avisos desaparecieron.
Si ejecuta un harness de agente en su Mac
Pregunte cuáles son sus interfaces locales y quién puede llamarlas. Dentro de un
workspace Bromure, bromure-cli vm ports <workspace> imprime los sockets en
escucha vivos del invitado, con puerto, protocolo, dirección y proceso, y las
ataduras solo a loopback marcadas. La tarjeta Listening Ports del panel de la VM
muestra lo mismo. Ese inventario es la pregunta sobre la que giró esta CVE, y un
solo comando la responde.
Si la interfaz también mira hacia fuera
La mitad remota de la CVE-2026-82533 necesitaba que el puerto fuera alcanzable. Las VM de workspace corren en una red NAT privada: son alcanzables desde su Mac, pero “no están expuestas en su LAN física, y las conexiones entrantes desde otro sitio no son posibles a menos que usted publique explícitamente un servicio”. Un puerto de control de agente sin autenticar al que la red de una cafetería no puede enrutar le deja un parche que aplicar a su propio ritmo.
Un confinamiento que se puede revocar es una preferencia
DeepSeek publicó una comprobación débil y la corrigió tres días después de que OX la confirmara. Lo duradero es lo que la comprobación estaba guardando. Una frontera trazada alrededor de un proceso por el propio entorno de ejecución de ese proceso es una frontera con la que el proceso puede negociar: tiene una dirección, una API y un objeto de ajustes con un campo dentro. En algún punto detrás de ese campo corre una ruta de código que decide si este llamante puede escribirlo, y una ruta de código de esa clase está a un mal valor por defecto de quedar en decorado.
Trace la frontera por debajo del proceso y no hay contraparte con la que negociar. El agente de un workspace Bromure tiene root, tiene el sistema de archivos entero y puede arrancar el servicio que quiera en el puerto que quiera. Sus claves de API son señuelos, su única ruta hacia la red es un socket virtio hasta un proxy en su Mac, y el archivo que guarda sus permisos está en un sitio que no puede leer. Entréguele al agente todo en su lado de la línea y deja usted de tener que defender la línea.
A los agentes de codificación les seguirán brotando planos de control locales, porque un plano de control es la forma de construir un panel, un puente con el IDE o un visor de diffs. Cada proyecto tiene entonces que responder si el código que ejecuta su agente está del mismo lado de la línea que los ajustes que gobiernan a ese agente. Falle eso y la autenticación pasa a ser lo único que aún aguanta, que es como un 9,4 se reduce a un solo comando de shell. Instale Bromure Agentic Coding y ponga el interruptor en algún sitio que su agente no pueda alcanzar.