Los investigadores de Apiiro han encontrado más de 100.000 ficheros .claude/settings.local.json subidos a repositorios públicos de GitHub. De esos, unos 1.100, de 63 organizaciones distintas, llevaban secretos dentro: contraseñas de bases de datos, tokens de API, claves privadas y hasta logins de root. Lo ha contado Ars Technica, y es de esas cosas que, cuando lo lees, piensas “pues claro”.
De dónde sale
Cuando Claude Code va a ejecutar un comando y te pregunta, una de las opciones es “Yes, and don’t ask again”. Al elegirla, la regla se guarda en .claude/settings.local.json para no volver a preguntarte. A veces se guarda como patrón, pero muchas veces se guarda el comando tal cual, con todo lo que llevaba dentro.
Así que si un día le dejaste ejecutar algo como esto:
psql "postgresql://admin:MiClaveDeVerdad@db.interno:5432/produccion" -c "select count(*) from pedidos"
ese comando, con la contraseña, se queda escrito en el fichero, más o menos así:
{
"permissions": {
"allow": [
"Bash(psql \"postgresql://admin:MiClaveDeVerdad@db.interno:5432/produccion\" -c \"select count(*) from pedidos\")"
]
}
}
Mientras el fichero se quede en tu máquina, no pasa gran cosa. El problema es que Claude Code lo añade al .gitignore global del usuario, no al del repositorio. Si clonas el repo en otra máquina, si una carpeta se convierte en repo más tarde o si alguien hace un git add . con prisa, el fichero entra en el commit. Y según Apiiro, en muchos casos es el propio Claude Code quien hace el commit sin que nadie se fije.
Lo más llamativo es que el problema estaba reportado desde agosto de 2025, y que esa y otras incidencias parecidas se cerraron solas tras 60 días sin actividad. Boris Cherny, de Claude Code, ha dicho que lo están mirando, y que estudian meter un escáner de secretos en la propia herramienta.
Lo que haría hoy mismo
Son cinco minutos y no hace falta esperar a ningún parche:
Añadirlo al
.gitignoredel repo, no fiarse del global. En el repo de este blog ya está así:echo ".claude/settings.local.json" >> .gitignoreComprobar si ya está subido, en el estado actual y en el historial:
git ls-files | grep settings.local.json git log --all --oneline -- .claude/settings.local.jsonRevisar qué hay dentro del fichero local, aunque no esté subido. Es muy fácil que tenga más de lo que recuerdas:
grep -nEi "password|passwd|token|secret|api[_-]?key|://[^:]+:[^@]+@" .claude/settings.local.jsonSi había un secreto en un repo público, rotarlo. Borrar el fichero o reescribir el historial no basta: los forks y los clones que ya existen siguen teniendo la copia.
No meter secretos en los comandos. Si el comando usa
psql "$DATABASE_URL", lo que se guarda es el nombre de la variable y no su valor. Variables de entorno, un.envfuera de git o un gestor de secretos hacen ese trabajo mucho mejor.
Los escáneres de secretos como gitleaks o TruffleHog ayudan, pero no son infalibles: de los 1.100 ficheros con secretos que encontró Apiiro, 215 no los detectaba ninguno de los dos. Mejor tenerlos, pero no como única defensa.
Lo que me llevo
Hace una semana escribía sobre Postman instalando plugins en Claude Code, Codex y Copilot por su cuenta, y aquí vuelve a salir lo mismo: los ficheros de configuración de los agentes se han convertido en una pieza más del proyecto, y no los vigilamos con el mismo cuidado que el código.
El “no volver a preguntar” es comodísimo, pero cada vez que lo pulsas estás escribiendo algo en un fichero. Conviene saber qué se escribe y dónde acaba ese fichero, porque una contraseña en texto plano no deja de serlo por estar dentro de un JSON que nadie mira.
Fuente: Apiiro, vía Ars Technica.




