El bloqueo fue la entrega
En la DEF CON 34 de esta semana, Tenet Security mostró un ataque que empieza con una petición que tu cortafuegos rechazará con toda seguridad. El 403 es precisamente el objetivo: el WAF escribe la petición bloqueada en el registro de seguridad, literal, y días después un agente de código lee ese registro para depurar los 403 y sigue las instrucciones que contiene. Ningún paso de la cadena está sin autorizar. Bromure Agentic Coding puntúa el texto al llegar y mantiene la credencial que necesita el agente secuestrado fuera de la máquina en la que se ejecuta.
El cortafuegos funcionó. Coincidió con la regla, devolvió un 403 y escribió en el registro la petición que rechazaba, tal como está diseñado. Esa entrada del registro es la vía por la que la carga útil llegó al agente de código.
La DEF CON 34 cerró esta mañana en Las Vegas. El viernes, Barak Sternberg, Nevo Poran y Ron Bobrov, de Tenet Security, dieron una charla cuyo título es también su argumento: Your WAF Blocked Us, That Was The Exploit. El resumen del programa dice “Remote Agent Takeover via Cloudflare, Sentry and Claude Zero-Day for data exfil”. La cobertura de síntesis llegó el 8 de agosto.
El mismo equipo bautizó en junio Agentjacking, tras demostrar que un informe de error falso de Sentry recuperado por MCP hacía que un agente de código ejecutara código controlado por el atacante en el 85 % de los intentos, en más de un centenar de instancias reales. La charla del viernes lo extiende a Seer, el agente del propio Sentry, cuyas recomendaciones envenenadas fluyen después aguas abajo hasta Cursor. La cadena de Cloudflare es el material nuevo.
El 403 es precisamente el objetivo
Empieza por el problema del atacante. No puede alcanzar tu agente de código. Se ejecuta en la máquina de una desarrolladora, detrás de todo lo que posees, y el atacante no tiene credencial, ni sesión, ni ruta de entrada.
Así que envía una petición construida para ser rechazada.
El WAF coincide con una regla gestionada y devuelve 403. También cumple la otra mitad de su trabajo y registra la petición que bloqueó, carga útil incluida, en el registro de eventos de seguridad. Una entrada que omitiera la carga útil sería inútil para el analista para el que existe.
Días después, alguien nota que el endpoint devuelve 403 y le pide a su agente
que lo mire. El agente llama al servidor MCP de observabilidad de Cloudflare,
uno de los
servidores oficiales que Cloudflare publica
para esto, y trae las filas de peticiones bloqueadas. El texto del atacante
llega dentro de un bloque tool_result, desde un servicio del propio
proveedor que la desarrolladora conectó, bajo un campo que significa esta es
una petición que rechazamos.
El agente lo lee como instrucciones. Después usa sus propias herramientas autorizadas de Cloudflare para reescribir registros DNS y redirigir el tráfico de clientes. Tenet sitúa la exposición en más de 15.000 organizaciones, incluido el 27 % del Fortune 1000.
No ocurre nada sin autorizar
Tenet llama al patrón la Authorized Intent Chain, y el texto de junio enuncia la consecuencia:
Recorre la cadena otra vez e intenta encontrar el paso sobre el que alertar. La desarrolladora autorizó al agente. El agente fue configurado con el servidor MCP. El servidor MCP consultó registros que existe para consultar. La cuenta que usó tiene el permiso de DNS que le concediste a propósito. Y la petición que dio origen a todo fue bloqueada. Cada control del camino hizo aquello para lo que se compró, y es la composición de esos comportamientos correctos lo que constituye el ataque.
Cualquier cosa que funcione preguntando quién está haciendo esto y si le está permitido responderá que sí en cada salto, porque la respuesta es sí. Quedan dos movimientos. Leer el texto en su camino de entrada, y poner la aplicación de la política en un sitio que el agente secuestrado no alcanza.
Puntuar el texto al llegar
Bromure Agentic Coding ejecuta el agente dentro de una VM Linux desechable en Apple Silicon y encamina cada byte de su tráfico por un proxy en el anfitrión, fuera de la caja en la que corre el agente. Eso incluye el tráfico del modelo, que es donde las filas de registro se convierten en instrucciones.
La salida de herramienta llega sin confianza
Bromure puntúa el contenido que el agente lee, incluidos contenidos de
archivos, páginas web y los bloques tool_result que vuelven de servidores
MCP y comandos de shell, con un modelo local de inyección de prompts. Ese
detector busca exactamente esto: una fila de registro que lleva un
imperativo dirigido a quien la lea. Puntúa el fragmento en sí, así que el
hecho de que Cloudflare lo entregue por una conexión que tú configuraste no
le compra nada a la carga útil.
Tú eliges qué hace una detección
Log and continue anota cada acierto en la ventana Security Log y deja pasar la petición. Ask me what to do pausa la petición saliente y te enseña el texto marcado, para que decidas con la frase delante. Block la detiene unilateralmente antes de que el modelo la lea, y el agente recibe un 451 seco que informa como un fallo de API.
Los archivos de autoridad tienen su propio clasificador
El envenenamiento de configuración era la otra mitad de la divulgación de
DEF CON. Un clasificador ModernBERT afinado puntúa los archivos que un
agente trata como órdenes permanentes, CLAUDE.md y AGENTS.md y
GROK.md y sus variantes anidadas y globales, junto a un escáner
determinista para las cargas útiles de ancho cero, bidireccionales y de
etiquetas Unicode que ningún modelo puede leer.
Se queda en tu Mac
Ambos detectores corren en el dispositivo, a partir de modelos que descargas una vez desde bromure.io. Puntuar tus registros de WAF de producción en busca de instrucciones inyectadas no implica enviar tus registros de WAF de producción a ninguna parte.
La escritura exige una clave que no está en la máquina
Supongamos que una carga útil pasa igualmente. El final de esta cadena es una llamada de API que cambia un registro DNS, y esa llamada necesita una credencial.
En un perfil de Bromure no está ahí para tomarla. Un token de Cloudflare entra
como una entrada Other API keys, que acuña un valor falso brm_… y lo
exporta a la VM bajo el nombre de variable de entorno que elijas. El token real
se queda en el anfitrión, y el proxy lo sustituye en el cable, en las
peticiones salientes hacia el único host de destino al que lo ataste. El
proceso del agente nunca lo tiene. Un dotfile o un historial de shell tampoco.
Activa Require approval to use para esa entrada y cada sustitución levanta un diálogo en macOS, fuera de la VM, antes de que Bromure reenvíe el valor real. Un agente secuestrado puede componer una actualización de DNS bien formada, y no puede responder al diálogo.
El resto del radio de acción tiene una respuesta más estricta. Guardrails es un motor de políticas que corre en el proxy del anfitrión y retira las operaciones destructivas de los protocolos que habla el agente: Kubernetes, AWS, DigitalOcean, registros de contenedores, GitHub, GitLab, Bitbucket y los endpoints HTTPS de bases de datos. Elige Block destructive o Read-only por recurso, y una llamada bloqueada vuelve como un 403 seco. Como es el anfitrión quien toma esa decisión, un agente que sigue instrucciones ajenas dentro de la VM no tiene nada que desactivar.
Un fallo de sandbox no mueve un hipervisor
La charla también divulgó un zero-day de Claude que elude el sandbox de red del agente para exfiltración completa de datos, más rootkits agénticos ensamblados a partir de inyección en memoria y envenenamiento de configuración que ningún EDR detecta. Ambos hallazgos apuntan al mismo punto débil: la contención con la que viene un agente es alcanzable desde dentro.
Bromure pone la frontera en otro sitio. La frontera es una máquina virtual, corriendo sobre el hipervisor de Apple con su propio kernel, tras NAT, con cada paquete cruzando un proxy que se ejecuta en macOS. Un defecto en el sandbox in-process del agente es un defecto dentro de la VM. No reubica la VM, y no le da al código de dentro de la VM una ruta a la red que se salte el proxy del anfitrión.
Y cuando algo sí aterriza ahí, aterriza en una máquina construida para tirarse.
Erase home borra /home/ubuntu, es decir dotfiles, .ssh, npm-global,
.cargo e historial de shell, y lo devuelve a su estado posterior al clonado.
Reset to base descarta todo cambio a nivel de sistema y vuelve a clonar el
disco de trabajo desde la imagen base. El rootkit que ningún escáner encuentra
sigue estando en una capa de disco que puedes borrar.
La cadena invisible, puesta por escrito
La observación más fuerte de Tenet es que la cadena se esconde a plena vista porque cada paso suyo es legítimo. No hay firma ni anomalía que correlacionar.
Bromure no intenta correlacionar ninguna. Cada petición que hace la VM cruza el proxy del anfitrión, y Bromure anota el host, el estado, la latencia y qué credenciales sustituyó. Las detecciones de inyección aterrizan en el Security Log con el texto marcado adjunto. Sube el nivel de traza y Bromure guarda también los cuerpos de las peticiones de IA, cifrados con la misma clave del llavero que los secretos de tu perfil.
Entonces puedes hacer otra pregunta: qué tocó esta sesión. Un agente que pasó la tarde leyendo registros de Cloudflare y luego hizo su primera llamada de la historia a la API de DNS son dos líneas que puedes leer, en la máquina donde corrió la sesión, sin agente que desplegar ni SIEM al que enrutar.
Cloudflare afinará su superficie, Sentry la suya, y las dos cadenas de la charla del viernes se cerrarán. Empareja cualquier sistema que registre entrada hostil con cualquier agente que lea registros para hacer su trabajo, y habrás reconstruido este ataque con dos piezas que hacen, las dos, su trabajo. Guardas registros para que alguien los lea, y ese lector ahora es un programa que actúa sobre lo que encuentra.
Basta con un instinto: trata todo lo que el agente lee como algo que puede haber escrito un desconocido, incluidas las partes que anotaron tus propias defensas.
Instala Bromure Agentic Coding, y pon entre el registro y el agente algo que revise el texto.