Amenazas · 22 de junio de 2026 · Rodrigo Gutiérrez
El agente perfecto también puede robar las llaves
Durante años, la cadena de suministro de software fue narrada como una historia de paquetes abandonados, typosquatting (suplantación de nombres casi idénticos), mantenedores agotados y dependencias invisibles que entraban por la puerta trasera de los proyectos. El atacante publicaba una librería con un nombre parecido al de una popular, esperaba un error de escritura, recogía algunas víctimas y desaparecía antes de que la comunidad terminara de mirar los logs. Era un modelo tosco, eficiente y algo deprimente: el phishing de siempre, pero empaquetado en JavaScript.
El caso de codexui-android pertenece a otra categoría. No se trata de un paquete desechable con olor a fraude desde el primer commit. Se trata de una herramienta útil, funcional, razonablemente pulida y conectada con una necesidad real: operar agentes de programación desde entornos remotos, móviles o alternativos. La promesa es irresistible para una generación de desarrolladores que ya no quiere sentarse frente al computador como si el código fuera una ceremonia bancaria. Quieren lanzar tareas desde el teléfono, mover sesiones entre dispositivos, automatizar revisiones, pedirle a un agente que edite un repositorio mientras ellos van camino a una reunión. En ese deseo legítimo aparece la grieta.
La superficie de ataque no fue una vulnerabilidad clásica en el sentido más cómodo del término. No hubo necesariamente una explotación espectacular de memoria, ni un cero día (vulnerabilidad desconocida por el fabricante) con nombre de misil. Hubo algo más incómodo para las organizaciones: una pieza de software que parecía pertenecer al futuro correcto. Una interfaz remota para agentes IA, un puente móvil, una solución práctica para una fricción real. El producto no era falso. El problema era que la utilidad era parte del camuflaje.
Ese detalle cambia el análisis. Cuando una herramienta resuelve un dolor, la inspección baja. Cuando además se instala desde un ecosistema conocido como npm (registro público de paquetes de JavaScript), viene enlazada desde GitHub y aparece conectada con una app Android, la mente del usuario completa el resto de la historia: si existe en varios lugares, si tiene comunidad, si funciona, si alguien ya la usó, entonces debe ser suficientemente confiable. Ese razonamiento era discutible en la vieja Internet. En la era de los agentes autónomos es derechamente peligroso.
La frase que debería quedar en el borde del monitor es simple: la confianza ya no se deposita en software; se deposita en identidades capaces de actuar. Y cuando esa identidad vive en un token (credencial digital que autoriza acciones sin pedir la contraseña cada vez), robar el token no es robar una contraseña más. Es tomar la silla del operador.
El robo que no necesitó parecer robo
Lo más elegante del caso, desde una perspectiva defensiva, es también lo más perturbador: el mecanismo no necesitaba convencer al usuario en cada ejecución. Bastaba con estar instalado. Según el análisis publicado, el paquete agregado en npm cargaba un fragmento al inicio, antes de que la aplicación hiciera su trabajo visible. Ese fragmento buscaba el archivo local de autenticación de Codex, normalmente auth.json, leía su contenido y enviaba el conjunto completo de credenciales hacia un servidor controlado por el atacante. No era una pantalla falsa. No era una petición sospechosa en medio de una sesión. No era un modal pidiendo permiso con una gramática digna de príncipe nigeriano. Era software haciendo lo que el sistema operativo permite hacer al software: leer archivos accesibles y abrir una conexión saliente.
El archivo atacado era especialmente sensible porque Codex, como otros asistentes modernos de desarrollo, necesita persistir autenticación para no obligar al usuario a iniciar sesión en cada arranque. Esa persistencia es una comodidad razonable cuando se entiende como parte de una experiencia local segura. Pero se transforma en un activo crítico cuando una herramienta de terceros corre dentro del mismo contexto del usuario. El access_token (token de acceso) permite operar durante una ventana determinada; el id_token (token de identidad) describe una sesión o usuario; el refresh_token (token de renovación) es la joya más problemática porque permite obtener nuevos tokens sin volver a pasar por el flujo completo de autenticación. En términos ejecutivos: si el access token es una tarjeta temporal, el refresh token puede parecerse demasiado a una máquina que imprime tarjetas nuevas.
El ataque tampoco requería que el código malicioso estuviera visible en el repositorio público revisado por la comunidad. Ese punto es central. Muchas organizaciones han desarrollado un reflejo de falsa seguridad: miran el repositorio, revisan estrellas, evalúan actividad, leen issues, observan commits recientes, y concluyen que la fuente es razonable. Pero en ecosistemas como npm, el artefacto publicado puede diferir del código visible en GitHub. La confianza en el repositorio y la confianza en el paquete instalable son dos objetos distintos, aunque el marketing del open source los haga parecer hermanos gemelos. En este caso, según el reporte, el código de exfiltración no estaba en el repositorio; estaba en el paquete distribuido.
Ahí aparece una lección severa para DevSecOps (integración de seguridad dentro del desarrollo y operación): la trazabilidad del código fuente ya no basta si no existe reproducibilidad verificable entre fuente, build y paquete publicado. La cadena no se protege mirando solo el origen; se protege comparando lo que se declara, lo que se compila, lo que se publica, lo que se instala y lo que efectivamente se ejecuta. Si falta una de esas capas, el atacante puede vivir exactamente en ese espacio intermedio. Ni dentro de la aplicación, ni fuera de ella. En la costura.
El detalle del dominio usado para exfiltrar también importa. La conexión saliente se presentaba como si perteneciera a telemetría o monitoreo, usando una nomenclatura que evocaba Sentry (plataforma común para observabilidad y errores). Para un desarrollador cansado, una conexión a algo parecido a “sentry” no prende fuego el tablero. Ese es el tipo de sutileza que distingue un fraude improvisado de una operación pensada para convivir con hábitos reales de ingeniería.
Android, WebView y la seducción de llevar el agente en el bolsillo
La extensión móvil del caso merece una lectura propia. La app “OpenClaw Codex Claude AI Agent” prometía algo muy atractivo: agentes de programación dentro de Android, con Codex CLI, OpenClaw y un entorno Linux embebido. Para muchos desarrolladores, eso suena casi poético. Un laboratorio portátil. Un copiloto dentro del teléfono. Un pequeño centro de comando en el bolsillo, sin root, sin Termux separado, sin depender de una estación de trabajo tradicional. La propuesta no es absurda; de hecho, representa hacia dónde se mueve el mercado: agentes ubicuos, persistentes, conversacionales, capaces de leer, modificar, compilar y coordinar trabajo desde cualquier superficie.
Pero esa misma promesa rompe varios supuestos de seguridad heredados. Android, visto desde el usuario final, es una plataforma de apps relativamente compartimentadas. Sin embargo, cuando una app empaqueta un Linux completo, ejecuta Node.js, levanta servicios locales, renderiza interfaces mediante WebView (componente que muestra contenido web dentro de una aplicación móvil) y descarga paquetes dinámicamente, el perímetro mental de “es solo una app” deja de servir. Lo que existe ahí es un pequeño entorno de ejecución con vida propia, capaz de operar como terminal, servidor, navegador interno, cliente OAuth (flujo de autorización), gestor de paquetes y consola de agentes. Mucho poder para algo que puede ser instalado con dos toques.
La cadena descrita indica que la app extraía un entorno Linux derivado de Termux, lo ejecutaba mediante PRoot (mecanismo que simula un entorno de archivos y procesos sin requerir root), instalaba codexui-android desde npm y levantaba la interfaz remota. Si la versión instalada no estaba fijada de manera estricta, el dispositivo podía terminar ejecutando la última versión publicada, con todo lo que eso implica. Aquí hay una idea poderosa para el artículo: el auto-update dejó de ser una comodidad; en agentes con credenciales, es una decisión de riesgo. Cada actualización no verificada puede cambiar la conducta de una identidad autorizada.
La contradicción con las declaraciones de privacidad visibles en tiendas móviles es todavía más delicada. Una ficha de aplicación puede declarar que no recopila datos ni comparte datos con terceros. Esa declaración puede ser útil como señal administrativa, pero no equivale a una garantía técnica. En entornos dinámicos, donde parte de la lógica se descarga después, donde un paquete externo gobierna ejecución, y donde el usuario inicia sesión dentro de un ecosistema embebido, la pregunta relevante no es solo qué declara la app. La pregunta es qué puede hacer cualquier componente que la app instala, ejecuta o actualiza después de pasar el umbral de confianza.
La movilidad agrava el problema porque mezcla entornos personales y corporativos. Un desarrollador puede instalar una app en su teléfono personal, iniciar sesión con una cuenta que tiene acceso a herramientas profesionales y producir una conexión invisible entre vida cotidiana, credenciales de trabajo y automatización de código. El teléfono deja de ser un segundo factor y se convierte en un primer entorno de ejecución. La política corporativa suele estar atrasada respecto de este punto. Prohíbe copiar código fuente a servicios externos, pero no siempre regula agentes móviles que pueden conectarse a repositorios, ejecutar comandos y persistir sesiones. Es como cerrar la puerta principal con biometría y dejar una ventana abierta para drones de delivery. Muy moderno, muy absurdo, muy 2026.
Cuando el token se vuelve identidad operativa
La palabra “token” suena pequeña. Parece un objeto técnico, algo intercambiable, casi administrativo. En realidad, dentro de un flujo de agentes IA, el token es una representación concentrada de confianza. Un agente no actúa porque tenga alma, aunque algunos productos insistan en venderlo como compañero de oficina con café imaginario. Actúa porque una identidad humana o de servicio le entregó autorización para leer, escribir, ejecutar, consultar APIs (interfaces de programación de aplicaciones), conectarse a repositorios y consumir capacidades de una plataforma. El token es el documento que permite esa acción.
En los asistentes de programación tradicionales, comprometer una API key (clave de acceso programática) ya era grave. En los agentes actuales, comprometer la credencial puede ser peor porque la herramienta no solo consulta un modelo. Puede operar dentro de un repositorio, leer contexto privado, aplicar parches, invocar comandos, consumir cuotas, generar cambios, abrir pull requests (propuestas de cambio en repositorios), interactuar con integraciones y crear trazas que parecen venir del usuario legítimo. El atacante que roba esa identidad no necesita necesariamente entrar por SSH, desplegar malware persistente ni quemar infraestructura. Puede utilizar el propio ecosistema autorizado para moverse con apariencia de productividad.
Aquí entra una diferencia estratégica entre credenciales humanas, credenciales de CI/CD (integración y despliegue continuos) y credenciales de agentes. Las credenciales humanas suelen estar protegidas por MFA (autenticación multifactor), sesiones vigiladas y controles de acceso condicional. Las credenciales de CI/CD suelen vivir en secret managers (gestores de secretos), con rotación y permisos acotados, al menos en organizaciones maduras. Las credenciales de agentes, en cambio, todavía están en una zona gris. Se instalan en laptops, extensiones, apps móviles, contenedores de desarrollo, servidores remotos, workspaces temporales y herramientas experimentales que nacen más rápido que la política corporativa. Son identidades con esteroides, pero gobernadas como si fueran plugins.
La documentación oficial de herramientas como Codex ya reconoce ese riesgo cuando recomienda tratar los archivos de autenticación como contraseñas, usar keyring (almacén seguro del sistema operativo), restringir métodos de login, evitar entornos no confiables y no exponer servidores de app en redes compartidas o públicas. El problema es que esas recomendaciones compiten contra la cultura real de desarrollo, donde el instalador rápido, el comando copiado desde GitHub y la promesa de “funciona en tu teléfono” tienen más fricción emocional que una política de seguridad escrita por alguien que no compila desde 2017. La seguridad pierde cuando llega tarde a una comodidad ya adoptada.
Por eso el caso de codexui-android debe leerse como un incidente de identidad, no solo como un incidente de paquete. El paquete fue el vehículo. La víctima real fue la autoridad delegada. El malware no buscaba destruir el dispositivo ni cifrar archivos. Buscaba una llave reusable para operar como alguien más dentro de una plataforma de IA. En organizaciones donde los agentes ya se conectan a repositorios internos, documentación privada, tickets, sistemas de build y canales de mensajería, esa llave puede transformarse en un pasaporte corporativo.
La defensa, entonces, no puede quedarse en “no instale paquetes sospechosos”. Esa frase es moralmente correcta y operativamente insuficiente. La defensa debe responder a una pregunta más dura: qué identidades de agentes existen, dónde viven sus credenciales, qué permisos tienen, qué paquetes pueden leerlas, qué procesos pueden exfiltrarlas, qué dominios pueden recibir tráfico y cuánto tiempo sobreviviría una credencial robada antes de ser revocada. Si la organización no puede responder eso con evidencia, no gobierna agentes; apenas los tolera.
La cadena de suministro de agentes ya no termina en el paquete
La cadena de suministro moderna se parece menos a una línea y más a una constelación. Un agente de programación puede depender de un binario en Rust, una interfaz en Vue, un paquete npm, una extensión de editor, una app móvil, un contenedor, un token OAuth, un repositorio GitHub, un túnel SSH, un WebSocket (canal de comunicación bidireccional), un servidor MCP (Model Context Protocol, estándar emergente para conectar modelos con herramientas externas), una skill descargada desde una comunidad y un conjunto de instrucciones persistentes. Cada pieza puede ser legítima. El riesgo aparece cuando todas se ensamblan con permisos acumulativos y auditoría parcial.
En la seguridad tradicional, el paquete malicioso era el problema porque corría código. En la seguridad de agentes, el paquete malicioso puede además influir en el comportamiento de una entidad que toma decisiones, escribe archivos y llama herramientas. Ese salto es fundamental. La exfiltración de tokens es solo una de las formas de abuso. Un paquete o skill también puede modificar instrucciones del agente, añadir un servidor MCP malicioso, alterar configuraciones de aprobación, esconder un hook (acción automática vinculada a un evento), cambiar rutas de build, inyectar dependencias futuras o provocar que el agente ejecute comandos con apariencia de flujo normal. La ejecución deja de ser una línea aislada; se vuelve conversación con efectos.
La investigación académica reciente ya apunta hacia ese borde. Los ataques contra ecosistemas de skills no necesitan gritar “haz algo malo”. Pueden esconder lógica maliciosa en ejemplos, plantillas o documentación que el agente reutiliza durante tareas normales. Esa es una idea brutal: el agente puede comprometerse no porque desobedezca, sino porque aprende obedientemente desde un material contaminado. En humanos, sería como entrenar a un nuevo empleado con un manual que incluye instrucciones invisibles para enviar las llaves de la oficina. En agentes, el manual puede terminar convertido en acción de shell.
Este escenario obliga a revisar la forma en que se evalúan las herramientas “local-first” (diseñadas para ejecutarse localmente). Lo local inspira confianza porque parece privado. Pero local no significa seguro si todo lo que corre localmente puede leer el mismo directorio de credenciales. Tampoco significa controlado si el software local descarga componentes remotos sin pinning (fijación estricta de versión), sin firma verificable, sin comparación reproducible y sin monitoreo de comportamiento. La privacidad del entorno local puede ser un espejismo si el primer paquete con permisos suficientes envía el secreto hacia afuera.
También se vuelve insuficiente el viejo SBOM (Software Bill of Materials, inventario de componentes de software) como fotografía estática. Un SBOM ayuda a saber qué dependencias existen, pero no siempre captura qué dependencia fue descargada en runtime (tiempo de ejecución), qué versión exacta quedó activa después de una actualización, qué código fue añadido durante build, qué sourcemap (mapa que conecta código compilado con fuente original) revela lógica no documentada o qué proceso abrió una conexión saliente anómala. En este tipo de caso, el inventario debe complementarse con telemetría de ejecución, egress control (control de tráfico saliente), comparación entre paquete publicado y repositorio, y detección de acceso a rutas sensibles como directorios de tokens.
La señal estratégica es clara: los agentes convierten la cadena de suministro en cadena de autoridad. Ya no basta saber qué librería se instaló. Hay que saber qué podía hacer esa librería cuando se encontró con una identidad autenticada.
Gobernar agentes sin matar la innovación
El error sería reaccionar con una prohibición torpe. Bloquear todo agente de programación, toda app móvil, toda extensión de editor y todo paquete experimental puede parecer prudente durante una semana, pero termina empujando el uso hacia rincones menos visibles. La innovación no desaparece porque seguridad frunza el ceño; solo cambia de ruta. El objetivo no debe ser frenar los agentes, sino sacarlos del territorio tribal donde cada desarrollador instala su propio laboratorio portátil sin trazabilidad. La organización madura no pregunta si habrá agentes. Pregunta bajo qué identidad, en qué entorno, con qué memoria, con qué permisos, con qué red, con qué auditoría y con qué botón real de revocación.
El primer principio debería ser separar comodidad de privilegio. Una UI remota para consultar o coordinar tareas no necesita necesariamente acceso completo a tokens persistentes. Una app móvil que muestra estado no debería heredar automáticamente credenciales capaces de ejecutar cambios en repositorios. Un entorno experimental no debería compartir el mismo CODEX_HOME que una estación de trabajo corporativa. Un agente en modo danger-full-access no debería convivir con secretos de largo plazo. La regla es sencilla de decir y difícil de implementar: la herramienta que mejora productividad no debe convertirse por accidente en custodio de identidad crítica.
El segundo principio es tratar credenciales de agentes como identidades de producción. Eso implica expiración corta, rotación, permisos mínimos, almacenamiento en keyring o secret manager, revocación centralizada, inventario por usuario y workflow, alertas por uso anómalo y bloqueo de credenciales en entornos no administrados. La cuenta humana puede seguir existiendo, pero el agente debe operar con permisos acotados y observables. En una arquitectura sana, un token robado no debería abrir una autopista; debería abrir una puerta pequeña, por poco tiempo, con cámara encima y alarma si alguien corre.
El tercer principio es validar el artefacto, no solo la marca. Las organizaciones deben comparar código fuente con paquete publicado, exigir versiones fijadas, retrasar actualizaciones automáticas de dependencias críticas, aplicar análisis de comportamiento a postinstall scripts (scripts que se ejecutan al instalar), revisar sourcemaps cuando existan, bloquear paquetes que acceden a rutas de credenciales sin justificación y observar conexiones salientes hacia dominios que imitan telemetría legítima. No se trata de convertir cada laptop en una cárcel, sino de asumir que el endpoint de desarrollo es un plano privilegiado de la empresa. En 2026, una estación de desarrollo puede tener más valor que muchos servidores internos.
El cuarto principio es diseñar zonas para experimentación. Los desarrolladores necesitan probar herramientas nuevas. La respuesta no es negar esa realidad; es ofrecer sandboxes corporativos (entornos aislados), contenedores efímeros, cuentas desechables, repositorios ficticios, tokens de baja capacidad y rutas aprobadas para evaluar agentes. Seguridad debe construir un “sí, pero aquí”, no un “no, jamás”. De lo contrario, alguien lo hará igual desde su teléfono, a las dos de la mañana, con una app que promete tres agentes en un APK. Y ahí el comité de riesgo no alcanza ni a ponerse los lentes.
El caso de codexui-android es una postal precisa del momento actual. La IA aplicada al desarrollo no está entrando por la sala de juntas; está entrando por extensiones, paquetes, scripts, apps móviles, repositorios virales y herramientas que nacen en comunidades antes de tocar procurement. Su valor es real. Su riesgo también. La defensa que entienda solo uno de esos dos lados va a fallar.
La frase final debería quedar incómodamente cómoda: cuando un agente puede actuar por usted, su credencial ya no es una contraseña; es una delegación de poder. Y toda delegación de poder, por brillante que parezca la interfaz, merece controles más serios que una estrella en GitHub y una promesa de productividad.