📻 Versión en audio: si prefieres escuchar en vez de leer, el resumen del artículo está justo aquí arriba.
Este 30 de octubre se filtró un hallazgo que debería incomodar a cualquiera que programe con agentes de IA: la extensión oficial de Claude Code para VS Code, distribuida desde la Cursor Marketplace, salió comprometida en la versión 2.1.313. No era una copia pirata ni un repo clonado: era el bundle oficial con un bloque malicioso inyectado al comienzo del archivo minificado. El equipo de seguridad Phorion publicó el análisis completo y Cursor retiró la versión de su tienda, además de sacar la 2.1.313 de npm y del registro de VS Code. Detalle importante: el código se ejecutaba apenas Node cargaba el archivo, antes del ciclo normal de la extensión. No hacía falta abrir ningún panel ni aceptar nada.
La cadena completa
El payload hacía cuatro cosas en orden casi quirúrgico. Primero, agregaba una llave pública Ed25519 a tu ~/.ssh/authorized_keys con el comentario svc-telemetry — un nombre que parece telemetría legítima de algún servicio del sistema, cuando en realidad era la llave del atacante. Segundo, intentaba activar el daemon SSH: systemctl en Linux, systemsetup en macOS, OpenSSH Server con PowerShell en Windows. Tercero, armaba un túnel SSH inverso hacia un servidor externo (134.209.82.225), con -R *:0:localhost:22: el atacante pedía un puerto dinámico en su máquina y todo lo que llegara ahí se reenviaba al puerto 22 de tu equipo, donde lo esperaba la llave plantada. Y cuarto, se aseguraba de volver después de un reinicio: crontab con @reboot en Linux, un LaunchAgent llamado com.apple.sysmond (disfrazado de proceso de Apple) en macOS, tarea programada SysMon en Windows. El script incluía un loop que reintentaba cada 60 segundos y sobrevivía al cierre del IDE, porque corregía en un proceso aparte.
El bug del atacante
Aquí viene la parte que a mí me pareció lo más didáctico del caso: el malware tenía un bug, y ese bug salvó a buena parte de los Mac. En macOS el script corría systemsetup -getremotelogin sin privilegios de administrador para checar si el Remote Login estaba apagado, y solo intentaba activarlo si el output decía «Off». Pero al correrlo como usuario normal, macOS responde «You need administrator access to run this tool… exiting!» — y sale con código 0. El script interpretaba eso como «SSH ya está encendido» y se saltaba el paso. Resultado: en un Mac que no tenía SSH ya corriendo, la llave quedaba plantada y el túnel conectaba hacia afuera, pero nadie podía entrar por el puerto local. Puerta plantada, casa cerrada.
Ojo: si tu Mac ya tenía Remote Login activado — y hay caleta de desarrolladores que lo tienen — la cadena completaba el circuito. Un bug del atacante no es una defensa que puedas cobrar.
Lo que más me preocupa no es el túnel
El paso final mandaba un beacon por HTTP con hostname, usuario, email de git configurado, IP pública y hasta 40 nombres de variables de entorno que hicieran match con KEY|TOKEN|SECRET|PASS|AWS|GCP. No robaba los valores: construía el inventario. Le decía al operador «estas máquinas tienen credenciales cloud, prioriza estas». Eso es reconocimiento de flota, no robo puntual — exactamente lo que uno hace cuando planifica moverse lateralmente por un parque de servidores.
Mi lectura: esto es supply chain de la capa donde todos estamos poniendo la confianza que le quitamos al código ajenjo. Extensiones, MCP servers, skills, plugins de IDE. La ironía es que la herramienta que te hace programar más rápido se convierte en el cable de entrada. Lecciones concretas, no lecciones bonitas: revisa fingerprints de llaves, no comentarios (el svc-telemetry pasó por legítimo); si publicas software distribuido a través de un registro, ese registro es superficie de ataque tuya; y las señales para cazar en una flota son específicas — com.apple.sysmond en LaunchAgents, ~/.config/.smt, entradas crontab @reboot raras, conexiones salientes al 134.209.82[.]225.
Yo ya revisé mis authorized_keys. Te sugiero lo mismo, y de paso mira qué tienes en Remote Login. La cadena completa del análisis está en la fuente.
Fuente de inspiración: Official Claude Code Extension Compromise: Security Advisory