Cuando Claude Code pregunta si puede ejecutar un comando y el usuario responde «sí, y no vuelvas a preguntar», el asistente guarda esa autorización en un archivo del proyecto llamado `.claude/settings.local.json`. Si el comando llevaba una contraseña dentro, la contraseña se guarda con él, en texto plano y sin aviso. Los investigadores de Apiiro encontraron 1.122 copias públicas de ese archivo con al menos un secreto dentro.
El trabajo se publicó el 5 de noviembre y lo firman Shmulik Cohen y Matan Giladi. Los números que lo sostienen son grandes: revisaron 104.185 copias públicas del archivo repartidas en 103.617 repositorios de GitHub, y en torno al 1,1% contenía credenciales reales. En conjunto, esas copias suman 1.379 secretos distintos. La investigación de Apiiro sobre credenciales de Claude Code describe el mecanismo con precisión: la regla guardada cubre solo lo que el aviso ofrecía, a veces un patrón como `npm test *` y a veces un comando exacto. En el segundo caso, cualquier contraseña o token tecleado en la línea queda escrito tal cual en el proyecto.
El archivo se sube solo si el repositorio se clona en otra máquina o si una carpeta se convierte en repositorio más tarde, y en muchos casos el propio Claude Code hace el commit sin intervención del usuario.
¿Qué hay dentro de esos archivos?
Más de un tercio de los secretos abren una base de datos directamente: 379 contraseñas de bases de datos, entre ellas una de producción en Azure PostgreSQL. Después aparecen 43 accesos SSH a servidores públicos, algunos con contraseña de root, y 42 tokens de GitHub, GitLab y npm.
La lista sigue con 23 claves de AWS, 122 claves de servicio de Supabase, 103 tokens de cuenta del mismo proveedor y seis claves privadas. Los investigadores también localizaron un token de producción de Square y credenciales asociadas a una aplicación que gestiona historiales médicos. En total, los archivos pertenecen a 63 organizaciones.
Ninguno de esos secretos se probó. Apiiro no intentó iniciar sesión ni contactó con ningún host, así que el trabajo documenta una exposición y no una brecha consumada. Una de las organizaciones avisadas confirmó que su clave seguía activa cuando recibió el aviso, que es el dato más cercano a una confirmación de daño real.
Protecciones que no cubren el caso
Claude Code hace algo razonable por defecto: la primera vez que escribe ese archivo en un repositorio, añade `**/.claude/settings.local.json` al fichero global de exclusiones de git del usuario. El problema es dónde vive esa protección, que es en la configuración de una persona en una máquina concreta.
No viaja con el proyecto, no cubre un archivo ya comprometido y no impide que otro miembro del equipo lo suba desde su propio entorno. De los 1.105 repositorios que los investigadores pudieron trazar, en 539 un commit con Claude como coautor había modificado el archivo, señal de que el asistente lo toca más a menudo de lo que sugiere la documentación.
El rastro tampoco desaparece al borrar el archivo. Las versiones antiguas guardadas en el historial de git suman otros 734 secretos en 509 repositorios que ya no tienen copia actual, y 211 bifurcaciones de 74 repositorios arrastran los mismos valores. De las 76.011 copias del archivo compartido `.claude/settings.json`, 298 contenían secretos.
El problema de los escáneres
No es el primer choque entre agentes y secretos: VOLTA ya usaba a Claude para tasar lo que robaba y OpenAI detectó 948 fallos en Linux con el mismo tipo de revisión automática.
La mitad de este incidente es de detección. Sobre los 1.122 archivos con secretos, gitleaks marcó 564 y TruffleHog marcó 643; 215 no los vio ninguno de los dos. La razón es que ambos buscan formatos conocidos de proveedor, y una contraseña escrita detrás de `PGPASSWORD=` o de `sshpass -p` parece una palabra más de la línea de comandos.
Ese hueco explica por qué el hallazgo importa más allá de Claude Code. Cualquier agente que guarde comandos completos en un archivo versionable reproduce el patrón, y los escáneres actuales no están hechos para leer comandos como si fueran credenciales.
De los 16 agentes de programación cuyas documentaciones comparó Apiiro, Claude Code es el único que guarda el comando completo en un archivo de proyecto por defecto. Ese detalle no absuelve al resto, pero marca dónde está la diferencia de diseño.
Cuidado de exponer tu repositorio
El orden correcto es rotar primero y limpiar después. Cambiar cada contraseña, token y clave que el archivo haya guardado alguna vez, y solo entonces reescribir el historial o borrar la copia, porque el valor ya está comprometido desde el momento en que se publicó.
El segundo paso es revisar el archivo en local aunque nunca se haya subido. Cualquier regla que contenga un secreto debe desaparecer, y las que se quieran conservar deberían apuntar a variables (`$DB_URL`) en lugar de a valores literales. Aprobar patrones como `Bash(npm run:*)` en vez de comandos sueltos reduce el problema en origen.
El tercero es de proceso. Si el equipo usa agentes que commitean solos, conviene añadir el archivo al `.gitignore` del proyecto y no fiarse del excludes global, y revisar los commits que tocan configuración local antes de empujar.
El problema de trabajar con agentes
La conversación sobre seguridad en asistentes de código se ha centrado en el prompt injection y en los permisos de red. Este caso señala un riesgo más doméstico: el asistente hace exactamente lo que se le pide y guarda el atajo, con el secreto dentro, en un archivo que el proyecto trata como configuración menor.
No hace falta un atacante sofisticado para convertir un comando aprobado en una filtración. Basta con que alguien suba la carpeta, con que un clon llegue a otra máquina o con que el propio agente haga el commit que el usuario no revisó.
En este punto, falta saber si Anthropic cambia el comportamiento por defecto, y falta una respuesta pública a los informes anteriores: los investigadores citan cuatro avisos relacionados, todos cerrados de forma automática y ninguno con respuesta de la empresa. Tampoco hay cifra de cuántas de las 63 organizaciones siguen con credenciales vivas.
Para quien trabaje con estos asistentes, la tarea de esta semana cabe en un comando: buscar `settings.local.json` en los repositorios propios, abrir los archivos y rotar lo que aparezca. Es más barato que explicar dentro de un año por qué la contraseña de producción estaba en un repositorio público.