Moví una Carpeta. Claude Code Me Dijo que No Copiara Mis Propios Secretos.

6 min read

Hacer commit de tu .env es un error grave. Claves de API robadas, credenciales expuestas, el desastre completo. La buena práctica es clara: pon tu .env en .gitignore y listo.

Excepto que .gitignore protege tu repositorio. No tu máquina.

Un paquete CLI malicioso no lee tu .gitignore. Lee tu disco. Agarra ~/.aws/credentials, tu historial de shell, tus claves SSH, tus wallets de crypto. Y ahora también lee .claude/settings.local.json (un archivo que probablemente nunca abriste).

Descubrí esto mientras movía toda mi carpeta de desarrollo fuera de iCloud después de que corrompiera mi cache de Node.js. Claude Code me dijo que no copiara mis propios secretos. Audité 50 proyectos. Ningún secreto vive en texto plano en mi máquina ya.

TLDR: .gitignore es un candado en la puerta principal. El malware entra por la ventana. Infisical detrás de una VPN mesh inyecta secretos en tiempo de ejecución. Nada en disco. Aquí está la configuración.

Cómic de dos paneles: trabajador de oficina rodeado de archivos .env expuestos confrontado por robot IA, luego desarrollador triunfante con dashboard VPN seguro y mascota langosta.
Cuando tu IA te pilla cometiendo crímenes contra la seguridad de credenciales.

El Teatro del .gitignore

Todos se ríen del dev que hace commit de un archivo .env. El consenso está establecido, cinco palabras, repetido en cada bootcamp y cada hilo de Twitter: ponlo en .gitignore.

Y claro. .gitignore es crucial. Primera línea de defensa. Nadie dice lo contrario.

El problema es tratarlo como la última.

.gitignore le dice a Git qué omitir. Eso es literalmente todo lo que hace. No tiene autoridad alguna sobre cualquier otra cosa ejecutándose en tu máquina. Un paquete npm comprometido, una dependencia pip envenenada, una extensión de VS Code maliciosa: ninguna revisa tu .gitignore antes de leer tus archivos. No necesitan hacerlo. Tienen acceso al disco. Se lo diste en el momento que ejecutaste npm install.

Andrej Karpathy, ex jefe de IA en Tesla y uno de los fundadores de OpenAI, descubrió esto por las malas con LiteLLM. Señaló un paquete typosquatted que tenía capacidades completas de lectura de disco: historial de shell, credenciales de cloud, claves SSH, configs de Docker, tokens de Kubernetes. Todo sentado en rutas conocidas, en texto plano, en máquinas de desarrolladores por todo el mundo.

Un grupo de amenazas que se hace llamar TeamPCP reclamó 500,000 credenciales robadas a través de múltiples campañas (números auto-reportados, no verificados independientemente, pero la técnica de exfiltración está documentada y es reproducible).

Todos mostraron el fuego. Nadie mostró el extintor.

Lo Que Tu Máquina Realmente Expone

Tu .gitignore cubre un directorio. El malware cubre toda tu carpeta home.

La exfiltración documentada de ataques de supply chain como LiteLLM se lee como una lista de compras: ~/.aws/credentials, contenidos de ~/.ssh/, cada archivo .env a través de cada proyecto (búsqueda recursiva, toma milisegundos), historial de shell con cada token que pegaste porque tenías prisa y pensaste "lo rotaré después" (no lo hiciste), credenciales de registry de Docker, tokens de Kubernetes, wallets de crypto.

Y la nueva entrada que nadie monitorea: .claude/settings.local.json.

Esa última es como me enteré. Estaba migrando un proyecto a ~/dev después de que el desastre de iCloud me forzó a mover todo. Claude Code marcó la operación de copia. Parafraseando: "No copies tu archivo de configuración, hay secretos de Supabase en texto plano en tus comandos auto-aprobados."

La herramienta que creó la fuga me advirtió sobre la fuga.

Había escrito todo un artículo sobre cómo CLAUDE.md es el nuevo .env y cómo la mayoría de desarrolladores lo tratan como un README. Mientras escribía eso, la carpeta .claude/ estaba silenciosamente filtrando los secretos reales. No el archivo CLAUDE.md en sí. El archivo de configuración al lado, donde Claude Code almacena cada comando que auto-aprobaste, textualmente, incluyendo los que tienen tus credenciales de base de datos.

Encontré esto un sábado por la mañana mientras mis hijos discutían sobre quién se queda con el último panqueque. Mi pantalla mostraba siete claves de Supabase en texto plano, y yo estaba ahí sentado pensando "¿cuánto tiempo ha estado así?". No fue un gran momento de panqueques.

La Semana Que Todo Se Desplomó

Esto no estaba planeado. Moví una carpeta, y cada arreglo reveló la siguiente capa.

iCloud estaba corrompiendo mi cache de Node.js. Crashes misteriosos en una máquina que debería haber manejado cualquier cosa que le lanzara. El arreglo fue simple: mover mis proyectos fuera de ~/Documents/dev a ~/dev, fuera del radio de sincronización de iCloud. Problema resuelto.

Excepto que mover 50 proyectos significa mirar 50 proyectos.

Ahí fue cuando empecé a abrir carpetas que no había tocado en meses. Archivos .env viejos por todas partes. Tokens hardcodeados en scripts que olvidé que existían. Y luego la auditoría de dependencias, que me llevó directo a un vector de ataque de supply chain escondido en mis dependencias pip que había estado auto-aprobando ciegamente por ocho meses. Mi agente de IA estaba ejecutando pip install en lo que quisiera, sin preguntas.

Asegurar las dependencias significó asegurar la red. Configuré una VPN mesh auto-hospedada que hace toda mi infraestructura invisible desde el internet público. Sin puertos abiertos, sin servicios expuestos, sin superficie de ataque para que los scanners encuentren.

Y la VPN mesh expuso la última pieza. Los secretos mismos. Aún sentados en texto plano en disco, aún legibles por cualquier cosa con acceso a archivos. Cuatro problemas apilados uno encima del otro, cada uno invisible hasta que arreglaras el de arriba.

Como quitar papel tapiz en una casa vieja y descubrir que la pared detrás está sostenida por optimismo.

Infisical Detrás del Mesh

Entonces, ¿qué reemplaza los secretos en texto plano en disco?

Infisical. Gestor de secretos open source, auto-hospedado, ejecutándose dentro de la VPN mesh detrás de Traefik. Accesible solo en infisical.mesh:8080. No expuesto al internet. Si no tienes un cliente Netbird autenticado y conectado, esa dirección simplemente no existe.

Docker Compose, Postgres, Redis, sentado en el mismo VPS que ejecuta el resto de mis cosas. El gestor de secretos mismo es invisible desde fuera del mesh. Esto importa. Una bóveda de secretos expuesta en una IP pública con una página de login es solo un objetivo más elegante. La mía no tiene IP pública. No hay página de login alcanzable desde afuera. No hay entrada DNS apuntando a ella.

Migré siete secretos de un solo proyecto. N8N_BASIC_AUTH_USER, SUPABASE_SERVICE_ROLE_KEY, VERCEL_OIDC_TOKEN, y cuatro más. Todos previamente en archivos .env en mi disco. Ahora viven en Infisical, organizados por proyecto y ambiente.

El flujo de trabajo apenas cambia: infisical run -- npm start. Secretos obtenidos en tiempo de ejecución, inyectados como variables de ambiente. Nada escrito a disco. Nada persiste después de que el proceso se detiene.

Si el malware escanea tu filesystem ahora, no hay .env que encontrar. No hay credenciales en el historial de shell. No hay tokens en comandos auto-aprobados.

Mientras limpiaba node_modules después del movimiento, también cambié a Bun. Huella más pequeña, no hay directorio gigante node_modules sentado ahí como un buffet para cualquier cosa escaneando el filesystem. No fue una decisión de seguridad, solo un efecto secundario de la limpieza. Menos superficie es menos superficie.

Entre escanear tu código por vulnerabilidades de dependencias y remover secretos del disco, cubres dos caras de la misma postura. Una vigila lo que entra. La otra se asegura de que no haya nada que robar si algo lo hace.

El Candado en la Puerta y la Ventana Abierta

El ataque de supply chain de LiteLLM mostró lo que un solo paquete envenenado puede hacer. Historial de shell leído, credenciales AWS agarradas, claves SSH copiadas. Documentado, reproducible, afectando miles de desarrolladores. Nadie mostró el extintor.

Abre tus últimos tres proyectos. Pregúntate dónde viven tus secretos. ¿En texto plano en disco? ¿En un .claude/settings.local.json que nunca abriste? ¿En historial de shell que un pip install malicioso puede leer en tres segundos?

Aseguré mi entorno de desarrollo. No más secretos en texto plano. No más cache de Node.js corrompido por sincronización en la nube. No más repositorios git rotos por interferencia del filesystem.

Un movimiento de carpeta. Una semana de cascada. La máquina está limpia.


Fuentes

Divulgación pública de Andrej Karpathy del ataque de typosquatting de LiteLLM. Documentación de IntCyberDigest sobre técnicas de exfiltración de TeamPCP y los incidentes de supply chain de Trivy.

(*) La portada es generada por IA. El cangrejo no fue dañado durante la producción, pero tu archivo .env sí.