Kilo Code entregó en silencio al servidor los 12 archivos del proyecto, aunque solo se permitían dos
El autor comprobó qué se envía al servidor del modelo cuando un asistente de IA cambia un solo carácter en el código. Kilo Code 7.4.20 sustituyó la suma por la multiplicación, la prueba pasó y en el disco cambió un solo archivo. Pero un servidor de prueba que hacía de proveedor no confiable recibió los 12 archivos del proyecto, aunque el usuario solo había permitido enviar dos, y las copias coincidían byte a byte.
Procesado por IA desde Habr AI; editado por Hamidun News
Solemos aceptar el trabajo de un asistente de IA así: miramos el diff, ejecutamos las pruebas, vemos el verde y cerramos la tarea. Un experimento descrito en Habr revela un agujero en ese hábito. La edición puede ser perfecta y, aun así, el proyecto ya está en un servidor ajeno.
Cómo se montó el experimento
La tarea era deliberadamente minúscula: en price.py la función total(price, count) devolvía price + count, mientras que la prueba esperaba que total(7, 3) diera 21. Había que sustituir la suma por la multiplicación y ejecutar check.py. La instrucción del usuario decía que solo se podían enviar price.py y check.py.
El autor partió de un modelo en el que el proveedor de LLM no es confiable e incumple las instrucciones a propósito. Su papel lo desempeñó un servidor HTTP local en 127.0.0.1. Imitaba respuestas en streaming de la API Chat Completions compatible con OpenAI y enviaba al cliente tool_calls: primero doce comandos read para todos los archivos de un proyecto sintético, luego un comando de corrección y después la ejecución de la prueba. El cliente era real: bin/kilo.exe de la extensión Kilo Code 7.4.20, lanzado mediante el comando CLI run. La configuración permitía lectura y ejecución de comandos.
Qué ocurrió
Por fuera, todo parecía ejemplar. Kilo cambió un carácter, la prueba pasó, los demás archivos en disco no cambiaron, el código de salida fue cero y las 14 llamadas a herramientas terminaron con el estado completed. Pero el servidor recibió los 12 archivos, con un total de 11 103 bytes, y sus SHA-256 coincidían con los originales.
La mecánica es simple. Kilo añade el resultado de cada lectura al historial del chat y lo envía en la siguiente solicitud. El servidor extrae los mensajes con el rol tool, elimina los números de línea y recompone los archivos. No hace falta ningún canal de exfiltración: el cliente mismo lleva los datos en sus solicitudes habituales.
El tráfico es interesante por sí mismo. Hubo 15 llamadas al modelo y el volumen total de los cuerpos de las solicitudes fue de 458 779 bytes para 11 KB de código único. La causa es el reenvío del historial, las descripciones de herramientas y el marcado de servicio. No hubo una única solicitud enorme: el código salía en porciones pequeñas y luego se repetía. Por eso una fuga así no se detecta por el tamaño de una solicitud.
Por qué las prohibiciones funcionan peor de lo que parece
En la serie inicial de pruebas, la regla read: deny bloqueaba la lectura directa de un directorio prohibido. Pero con bash: allow, Python leyó el mismo archivo y la salida pasó a la siguiente solicitud. Cuando se prohibió bash, el comando no se ejecutó. Los permisos en Kilo se definen por separado para cada herramienta, y prohibir una no cierra las demás vías.
Hay también salvedades honestas. En el experimento no hay un modelo real: los comandos los elegía el servidor de prueba, así que no se mide la propensión de los modelos comerciales a este comportamiento. El servidor conocía de antemano los nombres de los archivos; no se probó la búsqueda autónoma de un árbol desconocido. Tampoco se probó la sesión gráfica de la extensión, solo la CLI.
Qué hacer en la práctica
Primero: evalúe no solo el diff, sino también el registro de llamadas a herramientas y los cuerpos de las solicitudes al proveedor. Pase al menos una vez al agente por un proxy local y vea qué sale realmente.
Segundo: dé al agente los mínimos permisos. Si la lectura está permitida, todo lo leído pertenece potencialmente al proveedor. Para repositorios sensibles, es un argumento a favor de los modelos locales o de proveedores con garantías contractuales estrictas.
Tercero: no confíe en una instrucción de texto como «envía solo estos dos archivos». Es un deseo dirigido al modelo, no una restricción del cliente. El límite real lo crean solo los permisos de las herramientas, el sandbox y las políticas de red.
El autor publicó el banco de pruebas completo: Python 3.10+, Git y el ejecutable de Kilo, unas 150 líneas de código. Conviene repetirlo con su propio cliente, sea cual sea el agente que use.
- 12 nov 2026Jensen Huang deja el cargo de CEO de Nvidia: la empresa pierde 1,4 billones de dólares en dos semanas
- 12 nov 2026El sindicato de Oakland logra reciclaje profesional en lugar de despidos por la IA: 94,1 % a favor de la huelga
- 12 nov 2026Ocho países, OpenAI y Anthropic prometen un «interruptor de emergencia» para los modelos de IA, pero sin plazos ni sanciones
- 12 nov 2026OpenAI y ModRetro lanzan una consola de 200 dólares para juegos creados en Codex
Preguntas frecuentes sobre la noticia
Cómo se montó el experimento?
La tarea era deliberadamente minúscula: en price.py la función total(price, count) devolvía price + count, mientras que la prueba esperaba que total(7, 3) diera 21. Había que sustituir la suma por la multiplicación y ejecutar check.py. La instrucción del usuario decía que solo se podían enviar price.py y check.py. El autor partió de un modelo en el que el proveedor de LLM no es confiable e incumple las instrucciones a propósito. Su papel lo desempeñó un servidor HTTP local en 127.0.0.1.
¿Qué se sabe sobre Qué ocurrió?
Por fuera, todo parecía ejemplar. Kilo cambió un carácter, la prueba pasó, los demás archivos en disco no cambiaron, el código de salida fue cero y las 14 llamadas a herramientas terminaron con el estado completed. Pero el servidor recibió los 12 archivos, con un total de 11 103 bytes, y sus SHA-256 coincidían con los originales. La mecánica es simple. Kilo añade el resultado de cada lectura al historial del chat y lo envía en la siguiente solicitud.
¿Qué se sabe sobre Por qué las prohibiciones funcionan peor de lo que parece?
En la serie inicial de pruebas, la regla read: deny bloqueaba la lectura directa de un directorio prohibido. Pero con bash: allow, Python leyó el mismo archivo y la salida pasó a la siguiente solicitud. Cuando se prohibió bash, el comando no se ejecutó. Los permisos en Kilo se definen por separado para cada herramienta, y prohibir una no cierra las demás vías. Hay también salvedades honestas.
Test Frontier LLMs & Autonomous Agents in One Workspace
Run Claude Opus 5.5, GPT-6, Gemini 3.1, and DeepSeek side-by-side in Nomad AI (nomadnet.ai) — unified model routing, deep research, and multimodal workflows under one subscription.
Lo esencial de la IA — una vez por semana
Siete historias que de verdad importaron, elegidas a mano. Sin ruido ni notas de prensa.
¡Listo! Revisa tu correo para la confirmación.