Saltar al contenido
Lectura7 minPreview

Por qué se filtran los secretos

Bienvenida

Bienvenido a Secretos en Git: cómo no publicar sus llaves. Es para quien programa, administra sistemas o empieza en seguridad y ya usa Git y la terminal a nivel básico. Necesita Git y, para el laboratorio, gitleaks instalado.

Son cuatro lecciones cortas, un laboratorio en un repositorio de práctica y un quiz de 4 preguntas, unos 50 minutos. Al terminar sabrá por qué las llaves acaban en los repositorios, cómo evitarlo con .gitignore y variables de entorno, cómo detectarlas con gitleaks y el secret scanning de GitHub, y en qué orden actuar cuando una ya se publicó.

Qué es un secreto y por qué importa

Un secreto es cualquier dato que da acceso a algo: la contraseña de una base de datos, una llave de API, un token de GitHub, una llave privada SSH, las credenciales de una cuenta en la nube. Quien lo tiene no necesita vulnerar nada; le basta con usarlo. Por eso, en una auditoría de código, buscar secretos es de lo primero que se hace, y casi siempre aparece algo.

Git, creado en 2005, está diseñado para no perder nunca un cambio. Esa es su gracia y, para este tema, su problema: lo que entra al historial se queda ahí.

Cómo termina un secreto en un repositorio

Casi nunca es mala intención. Es prisa, un viernes a las cinco. Los caminos que más se repiten:

  • El .env subido por accidente. Si nadie lo excluye, un git add . lo mete junto con todo lo demás.
  • Credenciales escritas en el código. "Solo para probar", alguien pone la contraseña en app.py o en config.json, y la prueba llega a producción.
  • Respaldos y volcados. Un backup.sql, una id_rsa copiada a la carpeta del proyecto, el credentials.json que se descargó de la consola de la nube.
  • Registros. Un debug.log que imprime los encabezados de cada petición, token incluido.

El historial no olvida

Si usted sube un secreto y en el siguiente commit borra el archivo, el secreto sigue en el historial. Cualquiera que clone el repositorio lo recupera con dos comandos:

git log --all --oneline -- .env
git show 3f2a9c1:.env

El primero lista los commits de todas las ramas (--all) que tocaron la ruta escrita después de --. El segundo, git show COMMIT:RUTA, muestra el archivo tal como estaba en ese commit:

DB_PASSWORD=ClaveDePrueba2026
API_KEY=sk_test_ejemplo_no_real

Borrar el archivo cambia el presente del repositorio, no su pasado.

Tres commits en una línea de tiempo. El primero tiene solo el código. El segundo agrega un archivo .env con una llave. El tercero borra el .env, y HEAD apunta a él, así que el presente se ve limpio. Sin embargo, el commit 2 sigue en el historial y una persona atacante llega a su llave, resaltada en rojo.

Pero el commit 2 sigue en el historial: quien clone el repositorio lo lee con git show.

[fig] Borrar el archivo cambia el presente del repositorio, no su pasado. Si un secreto llegó al remoto, se trata como comprometido y se rota.

Quién lo encuentra primero

En repositorios públicos hay bots que revisan cada commit nuevo de GitHub buscando patrones de llaves. Los reportes de proveedores de nube y de seguridad describen llaves usadas por terceros a los pocos minutos de publicarse, típicamente para minar criptomonedas o mandar spam con la tarjeta del dueño.

Un repositorio privado ayuda, pero no basta: un colaborador externo, un cambio a público por error o una laptop robada con el clon adentro sacan el secreto igual.