Volver a todas las publicaciones
Publicado el · por Renaud Deraison

La página web reescribió la configuración del agente

El 21 de julio de 2026, Intezer y Kodem Security divulgaron CVE-2026-10591: una página de documentación de aspecto corriente llevaba instrucciones en texto blanco de un píxel, y cuando un desarrollador pidió al agente Kiro de AWS que la leyera, Kiro usó su propia herramienta de escritura de archivos para sobrescribir la configuración que lanza sus servidores MCP sin ninguna aprobación, luego recargó el archivo y ejecutó el código del atacante en el host, con los privilegios del desarrollador. AWS añadió un aviso de aprobación. Lo que perdura es que el agente, la web que lee y la máquina del desarrollador eran una sola zona de confianza. Bromure Agentic Coding pone un hipervisor entre ellos.

Un desarrollador pidió a Kiro que leyera una página de documentación. La página contenía una frase pintada en texto blanco de un píxel, escrita para el modelo, no para el ojo. Siguiéndola, Kiro reescribió el archivo que decide qué programas lanza, y luego lanzó uno. Nada de eso requirió un clic.

Kiro es el IDE agéntico de AWS: un agente de código que lee la web abierta en tu nombre, obtiene documentación y conecta herramientas por ti. Como la mayoría de los agentes en 2026, habla el Model Context Protocol, o MCP: el enchufe que permite a un agente de código llamar a herramientas externas y leer sus resultados. Kiro mantiene su lista de servidores MCP, y el comando exacto usado para iniciar cada uno, en un archivo sencillo en ~/.kiro/settings/mcp.json. Cuando ese archivo cambia, Kiro lo recarga y lanza lo que ahora describa.

Esa última frase es toda la vulnerabilidad. El archivo es un lanzador, y el agente puede escribir en él.

El 21 de julio de 2026, Intezer, en una investigación con Kodem Security, mostró la cadena que sigue, y The Hacker News la cubrió el mismo día. AWS asignó CVE-2026-10591, calificada con 8,8 sobre 10. Piezas anteriores del mismo problema ya habían sido señaladas por Johann Rehberger y por Cymulate. Lo que Intezer añadió fue la entrega.

Una página que lees, no un archivo que abriste

Las instrucciones no llegaron en un repositorio ni en una configuración en la que el desarrollador eligió confiar. Llegaron en una página web. Intezer las plantó en texto blanco de un píxel, color:#fff;font-size:1px, en una página de documentación de API por lo demás corriente. En un navegador, el párrafo no renderiza nada: una franja en blanco por la que un humano pasa de largo al desplazarse. Para el agente, que ingiere el texto de la página en lugar de su imagen, es un párrafo claro de instrucciones.

Esas instrucciones le decían a Kiro que usara fsWrite, su propia herramienta de escritura de archivos, para sobrescribir ~/.kiro/settings/mcp.json con una entrada suministrada por el atacante. Kiro lo hizo sin preguntar. Su modo Autopilot por defecto escribió el archivo por su cuenta, sin ningún cuadro de diálogo ni aviso de permitir esta escritura. El recargado se disparó, Kiro lanzó el comando de la nueva entrada, y el código del atacante se ejecutó en el host con los privilegios del desarrollador: suficiente para leer credenciales, copiar código fuente, instalar persistencia o moverse lateralmente hacia todo lo que la máquina del desarrollador pueda alcanzar.

La máquina del desarrollador — una zona de confianzaPágina docse ve normal alojo humano…texto blanco 1px:sobrescribir mcp.jsonAgente Kirolee la página comotexto, obedece,llama a fsWritemcp.jsonno una lista — unlanzador. Recargarcorre su comando.El código correcomo el dev:credenciales, código,nube, lateralNingún aviso de aprobación entre leer la página y ejecutar el código.CVE-2026-10591 — reportada feb. 2026, activa en v0.9.2 / v0.10.16, corregida en la serie v0.11.
CVE-2026-10591, de izquierda a derecha, todo en la máquina del desarrollador. Una página de documentación lleva instrucciones en texto blanco de un píxel, invisibles en el navegador y texto plano para el agente. Al pedírsele leer la página, Kiro sigue la instrucción de contrabando y usa su propia herramienta fsWrite para sobrescribir ~/.kiro/settings/mcp.json. Ese archivo es un lanzador: al recargar, Kiro inicia el comando que ahora nombra, ejecutando el código del atacante como el desarrollador, con acceso a credenciales, código fuente y sesiones en la nube en las que la máquina tiene sesión iniciada. Ningún aviso de aprobación se interponía entre leer la página y ejecutar el código.

AWS añadió un aviso. La máquina sigue siendo el premio.

La corrección es la sensata. AWS ahora marca mcp.json, .vscode/tasks.json, el directorio .git y otros archivos sensibles a la ejecución como rutas protegidas: escribir en cualquiera de ellos requiere aprobación explícita, tanto en modo Autopilot como Supervised. El paso de aprobación que faltaba ahora está. Si usas Kiro, actualízalo.

Lo que la corrección no cambia es la forma de la sala. AWS lo dijo al cerrar: un humano en el bucle solo funciona como control si se le muestra el paso que importa, y si la plataforma mantiene la línea incluso después de que al modelo lo hayan convencido por completo de cruzarla. Son dos exigencias. El aviso satisface la primera: saca a la luz la escritura. No puede satisfacer la segunda, porque cuando el código corre, corre en la propia máquina del desarrollador, con su propio alcance. Una aprobación que aceptas con un clic en una tarde cansada, o una aprobación que la próxima página astuta aprende a formular para que parezca rutinaria, te lleva al mismo lugar: el código del atacante ejecutándose donde viven tus claves, tus repositorios y tus sesiones en la nube.

La forma recurrente aquí — una página que el agente leyó, una configuración que podía escribir, un lanzamiento que podía disparar — no es específica de Kiro. Es el aspecto de un agente que lee la web abierta y edita archivos en una máquina llena de secretos. La pregunta duradera es dónde corre el agente, y qué hay a su alrededor cuando el aviso falla.

Donde Bromure ejecuta los mismos pasos

Bromure Agentic Coding no intenta hacer que el agente desconfíe de la página, rechace la escritura o atrape el clic. Cambia la máquina en la que corre toda la secuencia. El agente de cada perfil corre dentro de una VM Linux desechable en Apple Silicon, a un hipervisor de macOS. Ejecuta la cadena exacta de CVE-2026-10591 ahí y cada paso se dispara igual, y cada paso aterriza en otro lugar.

La página se lee. La inyección gana. El sustituto de Kiro reescribe mcp.json, el recargado se dispara, el comando del atacante se lanza con los privilegios del desarrollador. Salvo que dentro de la VM el desarrollador es el usuario ubuntu en una caja desechable, y la caja no guarda nada que valga el viaje. El código sale a buscar las credenciales que hacen rentable el ataque — la clave de Anthropic, las claves de AWS, el token de GitHub — y encuentra señuelos. En Bromure, los secretos reales nunca entran en la VM; un corredor de credenciales en el host inyecta marcadores como brm_…, un kubeconfig sintético y una clave SSH desechable, y solo intercambia el valor real en la frontera de red, en solicitudes a destinos que aprobaste. El robo de código fuente alcanza solo las carpetas que elegiste montar. El movimiento lateral hacia sistemas internos alcanza el cortafuegos de la VM de cada perfil.

Config normal — una máquinaPágina oculta → Kiro reescribe mcp.json →el código corre como tú, en tu MacClaves & tokens realesrobadosCódigo & nubeaccesiblesServidor MCP implantado persistetras reiniciosEl aviso era la única línea, y fue cruzada.Bromure Agentic Coding — VM desechableMisma cadena — dentro de la VM,como usuario ubuntu desechableAgarra señuelosbrm_… , no claves realesSalida filtradaproxy host, registradaCierra la sesión → caja reiniciaservidor implantado & persistencia fueraLa línea es el hipervisor, no el aviso.
El mismo ataque, dos máquinas. En una configuración normal (izquierda) el código inyectado corre en el Mac del desarrollador y alcanza las credenciales reales, el código fuente y las sesiones en la nube que viven al lado. Bajo Bromure Agentic Coding (derecha) la cadena idéntica corre dentro de una VM desechable: el código se ejecuta como un usuario ubuntu desechable, las credenciales que agarra son señuelos, sus solicitudes salientes se filtran y registran en el proxy del host, y cerrar la sesión reinicia la caja, borrando el servidor MCP implantado y cualquier persistencia. El hipervisor es la línea que el modelo no puede cruzar hablando.

Luego está la mitad saliente. Robar un señuelo solo compensa si puedes enviarlo a algún sitio, y moverse lateralmente significa alcanzar un segundo host. Ambas son acciones de red, y en Bromure ambas cruzan el proxy del host, donde el verdadero destino de una solicitud se filtra a la salida y donde la forma destructiva de una acción — un delete, un drop o un terminate contra las API de nube y git que el perfil expone — se topa con una barrera capaz de rechazarla, sin importar a qué convencieron al agente de hacer. Todo lo que el código lanzado intenta deja una línea registrada en el rastro de la sesión.

Y una capa se sitúa delante de todo esto, por una razón que encaja exactamente en este ataque. Bromure puntúa el contenido no confiable que un agente lee — una página obtenida o una respuesta de herramienta — con un detector de inyección en el dispositivo antes de que el modelo actúe sobre él. La razón por la que el texto de un píxel funciona es que una persona lee la página renderizada. El clasificador no; lee el mismo flujo crudo que lee el modelo, donde color:#fff;font-size:1px no oculta nada. El truco que hace el párrafo invisible a un ojo no cambia nada para un evaluador que lee los bytes. Atrapa la mayor parte de esto, y un disfraz suficientemente novedoso aún puede escapar a un solo detector, por eso se sitúa delante de la caja desechable en lugar de reemplazarla.

La web es ahora la entrada no confiable

Durante años, el consejo para los agentes de código era tener cuidado con qué repositorios confías. Kiro lleva la lección más allá: la entrada peligrosa era una página de documentación, del tipo que un agente lee cien veces al día, y el arma era una propiedad CSS que un navegador honra desde los años noventa. A medida que más del flujo de desarrollo pasa por agentes que leen la web abierta, cada página es entrada no confiable, y leerla con más cuidado no lo arregla.

El aviso que AWS añadió es el parche correcto, y debería lanzarse. Pero un control que depende de que una persona atrape la única escritura que importa, en cada página, para siempre, es un control con un mal historial a largo plazo. Bromure Agentic Coding no le pide al agente que tenga cuidado con la web. Asume que la página gana, que la configuración se reescribe y que el código corre, y se asegura de que, cuando todo eso ocurra, ocurra en una caja sin nada que llevarse y sin camino de vuelta. Esa es la diferencia entre un aviso que puedes sortear hablando y una línea trazada un nivel más abajo, donde hablar deja de funcionar. Instálalo y dale a tu agente una máquina que no es tuya para perder.