Tu Archivo .env Está Público — Cómo Descubrirlo y Arreglarlo
¿Tu archivo .env está expuesto en producción? Aprende a detectar variables de entorno expuestas y a arreglarlas antes de que alguien más las encuentre.
Rod
Founder & Developer
Si sospechas que tu archivo .env está público — ya sea en GitHub o accesible desde tu URL de producción — tienes que actuar rápido. Hay bots automatizados que escanean repos en tiempo real. El tiempo de exposición real se mide en minutos.
Esta guía te dice exactamente qué hacer, en qué orden.
Primero: verifica si realmente está expuesto
Antes de entrar en pánico, confirma el problema. Hay dos formas en que el .env puede quedar expuesto:
Opción 1: accesible desde tu URL de producción
Algunos servidores web mal configurados sirven archivos estáticos sin filtrar. Para verificarlo:
# Prueba directamente en el navegador o con curl
curl https://tu-dominio.com/.env
curl https://tu-dominio.com/.env.local
curl https://tu-dominio.com/.env.productionSi el servidor responde con texto plano y ves variables de entorno, el archivo está expuesto públicamente. Cualquiera puede acceder a él.
También puedes usar la herramienta de escaneo de env expuesto gratis de Data Hogo para verificarlo en segundos.
Opción 2: en el historial de Git
# Busca si el .env está trackeado o estuvo en algún commit
git log --all --full-history -- .env
git log --all --full-history -- .env.local
git log --all --full-history -- "*.env"Si el output muestra commits, el archivo estuvo en el historial en algún momento. Aunque lo hayas borrado después, sigue ahí.
Si está expuesto: el orden correcto de acciones
Este es el error que comete la mayoría: van directo a borrar el archivo del repo antes de rotar las credenciales. No hagas eso. El orden importa.
Paso 1: Rota todas las credenciales expuestas AHORA
Antes de tocar el repo, ve a cada servicio y revoca las credenciales que estaban en el archivo:
- Stripe: Dashboard → Developers → API Keys → Revoke
- OpenAI: Platform → API Keys → Delete
- Supabase: Dashboard → Settings → API → Reveal → Regenerate
- GitHub tokens: Settings → Developer Settings → Personal Access Tokens → Delete
- Cualquier otro servicio: busca "API Keys" o "Tokens" en la configuración
Genera nuevas credenciales para cada una. Las keys viejas quedan inválidas.
Si alguien ya usó las credenciales expuestas, rotar las keys los saca inmediatamente. Si todavía no las usaron, las invalidas antes de que puedan.
Paso 2: Verifica si ya te usaron las credenciales
Revisa los logs de cada servicio antes de cerrar:
# En Stripe: revisa transacciones no reconocidas
# En OpenAI: revisa el uso de la API en los últimos días
# En Supabase: revisa los logs de autenticación
# En GitHub: revisa actividad reciente en repos y OAuth appsSi ves actividad que no reconoces, el problema es más grande. Contacta al soporte del servicio afectado y documenta todo.
Paso 3: Saca el .env del historial de Git
Borrar el archivo con git rm no elimina el historial. Necesitas reescribir los commits.
La herramienta más segura es git-filter-repo:
# Instala git-filter-repo (Python)
pip install git-filter-repo
# Elimina el archivo de todo el historial
git filter-repo --path .env --invert-paths --force
git filter-repo --path .env.local --invert-paths --forceEsto reescribe el historial. Si tienes collaborators o forks, necesitan hacer git clone de nuevo porque sus historiales ya no van a ser compatibles.
Para repos con mucha historia, el BFG Repo Cleaner es más rápido:
# Descarga el jar de BFG y corre
java -jar bfg.jar --delete-files .env tu-repo.git
git reflog expire --expire=now --all && git gc --prune=now --aggressivePaso 4: Fuerza el push del historial limpio
# Esto sobreescribe el historial remoto
git push origin --force --all
git push origin --force --tagsPara repos públicos en GitHub, también contacta a soporte para que vacíen los caches — GitHub puede tener copias cacheadas del contenido antiguo.
Cómo prevenir que vuelva a pasar
.gitignore correcto desde el inicio
# Agrega esto ANTES del primer commit
echo ".env" >> .gitignore
echo ".env.local" >> .gitignore
echo ".env.production" >> .gitignore
echo ".env.*.local" >> .gitignore
git add .gitignore
git commit -m "chore: add env files to gitignore"El .gitignore solo funciona para archivos que no están trackeados todavía. Si el .env ya está en el repo, primero sácalo del tracking:
git rm --cached .env
git commit -m "chore: untrack .env file".env.example con valores ficticios
La práctica estándar es tener un .env.example en el repo que muestra qué variables se necesitan, sin los valores reales:
# .env.example — esto SÍ va en Git
STRIPE_SECRET_KEY=sk_live_your_key_here
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
OPENAI_API_KEY=sk-your_openai_key
DATABASE_URL=postgresql://user:password@host:5432/dbNunca pongas valores reales en .env.example. Ni de staging. Ni de desarrollo. Usa siempre valores ficticios obvios.
Pre-commit hook para detectar secretos
# Instala git-secrets
brew install git-secrets # macOS
# o
pip install detect-secrets # multiplataforma
# Configura para detectar patrones comunes de API keys
git secrets --install
git secrets --register-aws # Detecta keys de AWS automáticamenteEsto bloquea el commit si detecta patrones que parecen credenciales — antes de que lleguen al repo.
Si tu .env estaba en producción como archivo estático
Esto pasa en setups con Nginx o Apache mal configurados, o cuando subes archivos estáticos directamente a S3.
Para Nginx, agrega esto a tu configuración:
# Bloquea acceso a archivos de configuración
location ~ /\. {
deny all;
return 404;
}Para verificar que está bloqueado:
curl -I https://tu-dominio.com/.env
# Debe devolver 403 o 404, nunca 200Escanea tu repo para encontrar más problemas
El .env expuesto raramente es el único problema. Al escanear repos después de un incidente de este tipo, encontramos credenciales adicionales commiteadas directamente en el código — API keys hardcodeadas en archivos JavaScript, tokens en archivos de configuración, passwords en comentarios.
Data Hogo detecta secretos en el código fuente y en el historial de Git, dependencias vulnerables, y patrones de código inseguros. El escaneo tarda menos de 5 minutos.
Si quieres entender el panorama completo de cómo el código generado por IA maneja mal las credenciales, ese artículo explica los patrones más comunes.
Preguntas frecuentes
¿Qué pasa si mi archivo .env está en un repo público de GitHub?
Los bots que escanean GitHub en busca de credenciales actúan en segundos — no minutos. Si tu .env llegó a un repo público, asume que las credenciales ya fueron vistas. El primer paso es revocar y rotar todas las API keys y tokens inmediatamente, incluso antes de borrar el archivo del historial de Git.
¿Cómo sé si mi .env está accesible desde mi URL en producción?
Intenta acceder a https://tu-dominio.com/.env directamente en el navegador. Si ves texto plano con variables, está expuesto. También puedes usar la herramienta gratuita de Data Hogo en datahogo.com/es/tools/env-check para verificarlo automáticamente.
¿Borrar el archivo .env del repo lo elimina del historial de Git?
No. Git guarda todo el historial de commits. Si el archivo estuvo en algún commit, sigue en el historial aunque lo hayas borrado después. Para eliminarlo completamente necesitas reescribir el historial con git filter-repo o BFG Repo Cleaner.
¿Cuánto tiempo tengo para arreglar un .env expuesto antes de que lo encuentren?
Minutos, no días. Hay bots automatizados que escanean commits nuevos en GitHub en tiempo real buscando patrones de API keys. Para repos públicos, el tiempo de exposición relevante es el que tardas en darte cuenta — no el que tardas en arreglarlo. Rota las credenciales primero, limpia el historial después.
¿Cómo prevengo que el .env vuelva a quedar expuesto?
Tres pasos: agrega .env* a tu .gitignore antes del primer commit, nunca pongas credenciales reales en .env.example (usa valores ficticios), y configura un pre-commit hook con herramientas como git-secrets para detectar patrones de API keys antes de que lleguen al repo.
Posts Relacionados
OWASP A09 Registro y Monitoreo
OWASP A09 explica por qué las brechas tardan 204 días en detectarse. Aprende qué registrar, qué nunca guardar en logs, y cómo corregir los fallos silenciosos en tu app.
OWASP A10 SSRF para Desarrolladores
SSRF permite a atacantes hacer que tu servidor consulte recursos internos — incluyendo credenciales de AWS. Esta guía explica cómo funciona y cómo prevenirlo.
OWASP A05 Configuración Insegura
El 90% de las aplicaciones tiene alguna configuración insegura. Aprende qué cubre OWASP A05:2021, ve el código vulnerable vs. seguro en Next.js, y corrígelo ya.