Archivo .env expuesto — respuesta al incidente en 30 minutos | Scanthra
Mayo de 2026https://tusitio.com/.env devuelve
tus claves de API, contraseña de base de datos y credenciales SMTP, trátalo como un
ataque activo aunque nadie las haya usado todavía. Rota todo,
audita el uso y luego bloquea la ruta. Planifica 30 minutos de trabajo concentrado
y unos días de seguimiento.
Por qué un .env expuesto es grave
Un archivo .env suele contener:
- Usuario, contraseña y host de la base de datos.
- Claves de API de Stripe, AWS, SendGrid, Mailgun, OpenAI…
- Secretos de firma JWT y secretos de cliente OAuth.
- A veces credenciales de administrador o «contraseñas DEV» usadas en la inicialización.
Escáneres de Internet como
Shodan, BinaryEdge y decenas de botnets de recolección de credenciales
buscan continuamente /.env en millones de hosts. Si el tuyo es público,
asume que alguien ya lo ha leído. El coste de rotar es mucho menor
que el coste de una filtración de datos.
Paso 1 — Rota cada secreto del archivo
Abre el archivo (o tu copia de seguridad) y para cada entrada:
- DB_PASSWORD — cámbiala en tu base de datos
(
ALTER USER … WITH PASSWORD …en PostgreSQL,ALTER USER … IDENTIFIED BY …en MySQL), y luego actualiza la configuración de tu aplicación. - Claves de API — para cada proveedor, ve al panel → Claves de API → revoca la clave filtrada, genera una nueva y actualiza la configuración. Stripe, AWS y OpenAI admiten rotación en vivo sin tiempo de inactividad.
- Secretos JWT / de sesión — rótalos; ten en cuenta que esto cerrará la sesión de todos los usuarios. Prográmalo en una franja de poco tráfico si es necesario, pero no lo retrases más de unas pocas horas.
- Credenciales SMTP / del servicio de correo — rótalas de inmediato; las credenciales SMTP filtradas son el vector número 1 de spam.
Usa un gestor de contraseñas o tu gestor de secretos (AWS Secrets Manager, Doppler, 1Password, Bitwarden) para generar los nuevos valores. No reutilices ninguno de los secretos anteriores.
Paso 2 — Audita el uso de las claves filtradas
Antes de olvidar las claves antiguas, comprueba si alguien las usó mientras estuvieron expuestas:
- Stripe: Panel → Desarrolladores → Eventos. Filtra por tu clave antigua. Busca cargos, reembolsos o cambios de cuenta que no hayas realizado tú.
- AWS: Historial de eventos de CloudTrail filtrado por el
ID de clave de acceso filtrada. Busca nuevos usuarios IAM, nuevas instancias EC2,
lecturas de buckets S3 inesperados, cualquier cosa con
iam:*oec2:RunInstances. - SendGrid / Mailgun: feed de actividad en busca de picos, nuevas plantillas añadidas o cambios de IP.
- Base de datos: registros de auditoría (si están habilitados) en busca de
consultas inesperadas; comprueba
pg_stat_activitypara las sesiones actuales.
Si encuentras algo sospechoso: es un incidente confirmado — escálalo, regístralo, sigue tu plan de respuesta a incidentes y notifica a los clientes si hay datos personales implicados. Las entidades bajo NIS2 (directiva UE de ciberseguridad) deben presentar una alerta temprana en un plazo de 24 horas.
Paso 3 — Bloquea la ruta definitivamente
El archivo filtrado probablemente estaba en la raíz de tu aplicación porque el directorio raíz del framework era un nivel demasiado alto. Dos capas de defensa son mejores que una:
Mueve el archivo fuera del directorio raíz web:
mkdir /etc/myapp
mv /var/www/myapp/.env /etc/myapp/.env
chmod 600 /etc/myapp/.env
chown www-data:www-data /etc/myapp/.env
Actualiza tu aplicación para leer desde la nueva ruta.
Y bloquea los archivos de puntos en el servidor web:
# nginx
location ~ /\.(?!well-known) { deny all; return 404; }
# Apache
<FilesMatch "^\.">
Require all denied
</FilesMatch>
Paso 4 — Asegúrate de que no vuelva a ocurrir
- Usa un gestor de secretos en producción —
AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault, Doppler.
El archivo
.envse convierte en una comodidad para el desarrollo, no en un artefacto de despliegue. - Añade una verificación en CI que falle la compilación si
.envestá confirmado.git secrets,trufflehogogitleakshacen esto. - Instala un hook pre-commit con
detect-secretspara que las filtraciones no lleguen ni a main. - Rota periódicamente de todas formas. Cada 6 meses para claves de larga duración; de inmediato cuando un miembro del equipo se va.
¿Qué pasa con el historial de Git?
Si .env se confirmó alguna vez en un repositorio público — aunque fuera
brevemente, aunque fuera hace años — asume que los secretos están filtrados. La búsqueda de GitHub
y miles de scrapers de datos de entrenamiento ya lo tienen. git filter-repo
reescribe el historial, pero aun así necesitas rotar los valores, porque
existen copias fuera de tu control.
La lección aburrida
El .env expuesto es uno de los problemas detectados más comunes por Scanthra
en proyectos PHP, Laravel, Django, Rails y Node. La causa raíz
es casi siempre «seguí un tutorial que ponía .env en la raíz del proyecto
y olvidé que el servidor web sirve archivos estáticos desde allí.»
Mover el archivo un directorio hacia arriba — y añadir la regla de bloqueo de dotfiles —
cierra por completo esa clase de vulnerabilidad.
Cómo lo detecta Scanthra
Nuestro módulo Archivos Ocultos comprueba una lista blanca de rutas
que incluye .env, .env.local,
.env.production, .git/config,
/backup.sql, /dump.sql, /wp-config.php.bak
y más. Lo complementamos con comprobaciones de magic-bytes (ZIP, gzip,
cabeceras SQLite) para distinguir una copia de seguridad real de una página 404 que
devuelve 200 por error.
¿Quieres saber si tu sitio tiene este problema?
Scanthra hace una revisión pasiva y amigable, y te envía por correo electrónico un informe de seguridad en PDF fácil de entender.
Analiza tu sitio gratis