.env es comodísimo y casi todos los frameworks modernos lo usan. Pero colócalo en el sitio equivocado una sola vez y cualquiera podrá leer todos los secretos que contiene. Aquí tienes qué es y cómo protegerlo, desde cero.
Un poco más de detalle
Las apps tienen "valores que cambian por entorno" y "valores que no quieres que nadie vea": la contraseña de la BD, las claves de API externas, la clave que cifra las sesiones. Si las codificas a fuego en el código fuente, los secretos se filtran en el momento en que compartes el código.
Así que las reúnes en un único archivo .env y las lees como "variables de entorno" desde el código. Next.js, Laravel, Rails y muchos frameworks funcionan así.
El contenido es texto plano, una línea NOMBRE=valor por ajuste (los valores de abajo son de ejemplo).
APP_ENV=production
DB_HOST=127.0.0.1
DB_PASSWORD=your-db-password-here
PAYMENT_API_KEY=your-payment-api-key-hereMantener la configuración fuera del código lo popularizó la guía de diseño de aplicaciones web «The Twelve-Factor App». Su prueba para saber si la configuración está bien separada es si el código podría publicarse como código abierto en cualquier momento sin comprometer ninguna credencial. .env es un contenedor práctico de esa idea durante el desarrollo.
En qué se diferencia de cosas parecidas
Estas son las cosas que más se confunden con .env. Solo algunas son un lugar seguro para secretos.
| Nombre | Qué es | ¿Vale para secretos? |
|---|---|---|
| Variables de entorno | Valores que el sistema operativo o el contenedor pasan a un proceso en ejecución | Sí (lo habitual en producción) |
.env | Variables de entorno reunidas en un archivo | Sí, pero nunca en un directorio público ni en Git |
.env.example | Un ejemplo que lista los nombres con valores vacíos | No (está pensado para subirse al repositorio) |
NEXT_PUBLIC_* / VITE_* | Variables incrustadas en el JavaScript del navegador | No (cualquiera puede leerlas) |
| Gestor de secretos | Un servicio en la nube para guardar valores secretos | Sí; se gestiona con permisos y registros de auditoría |
La cuarta fila es la que se pasa por alto. Next.js incrusta los valores de las variables que empiezan por NEXT_PUBLIC_, y Vite los de las que empiezan por VITE_, en el JavaScript que se envía al navegador al compilar. Aunque esté en .env, una variable con uno de estos prefijos se vuelve pública.
Por qué es el "archivo más peligroso"
Porque varias claves están en un solo archivo, una única exposición propaga el daño rápido. Enumerar "qué desbloquea cada valor filtrado" deja clara la gravedad.
| Valor filtrado | Qué pasa |
|---|---|
| Credenciales de BD | leer / alterar / borrar datos |
| Claves de API externa | uso suplantando identidad, facturación fraudulenta |
Clave de cifrado (p. ej. APP_KEY de Laravel, claves de firma) | falsificación de sesiones, inicio de sesión suplantado |
| Secretos de OAuth | secuestro de las apps vinculadas |
De hecho, exponer .env es un incidente clásico. → El .env expuesto a todo el mundo
Casos reales: archivos .env expuestos como objetivo
- Una operación de extorsión a gran escala (2024): el equipo de investigación de una empresa de seguridad informó de una actividad que apuntó a 110.000 dominios, recopiló archivos
.envexpuestos en servidores web, usó las credenciales de nube que contenían para llevarse datos y exigió un rescate. Se recopilaron más de 90.000 variables, unas 7.000 de ellas de servicios en la nube y unas 1.500 de cuentas de redes sociales. La causa no fue una vulnerabilidad del proveedor de nube, sino una mala configuración de las organizaciones que expusieron sus archivos.env - Vercel (abril de 2026): un acceso no autorizado a sistemas internos llevó a que se leyeran variables de entorno de algunos clientes, las guardadas en la categoría cuyos valores pueden volver a mostrarse → análisis completo (en inglés)
- Repositorios públicos (un estudio de 2026): más de 540.000 credenciales publicadas en GitHub seguían siendo válidas en el momento del estudio. Borrar el archivo o el historial no sirve si la credencial no se revoca → análisis completo (en inglés)
El primer caso muestra que los .env expuestos no los encuentra gente navegando: se recopilan de forma automática y a gran escala. No des por hecho que un sitio pequeño no será encontrado.
La filtración típica = un error de colocación
La causa principal es "poner toda la app en el directorio público (docroot)". Donde solo debería servirse public/, exponer su carpeta superior hace que .env también sea alcanzable.
✗ Peligroso (la app en la raíz pública)
public_html/ ├─ .env ← ¡legible! ├─ app/ └─ public/
✓ Seguro (la app fuera, solo public servido)
app-root/ ├─ .env ← inalcanzable ├─ app/ └─ public_html/ → public/
Además de la colocación, también se filtra por estas vías:
- Subirlo a Git (público al instante en un repositorio público; visible para todos los que tienen acceso en uno privado)
- Dejar copias como
.env.bako.env.olden el directorio público - Distribuir una imagen de contenedor o un zip con
.envtodavía dentro - Poner secretos en variables
NEXT_PUBLIC_/VITE_, como se explica arriba
Cómo protegerlo
No lo pongas en un directorio público
Mantén la app fuera del docroot; sirve solo public/. Pasos concretos para hosting compartido: esta guía.
No lo subas a git
Añade .env* a .gitignore y comparte solo un .env.example con valores vacíos.
Rota todo si se filtra
No solo la clave confirmada: reemplaza todas las claves que estaban en .env. Actúa como si todas se hubieran visto.
Autocompruébalo con regularidad
Adquiere el hábito de comprobar que /.env no se puede abrir en tu propio sitio.
Cómo revisar tu sitio y tu repositorio
Autocomprobación (solo contra dominios que poseas)
# Un 200 con cuerpo significa que está expuesto. 403/404 está bien por ahora.
curl -sI https://tudominio/.env | head -1
curl -sI https://tudominio/.git/config | head -1Comprobar esto en cada despliegue detecta los errores de colocación a tiempo.
Revisa tanto el exterior del sitio como el interior del repositorio.
- Para un sitio cuya propiedad hayas verificado, la auditoría de seguridad del sitio revisa de una vez
/.env,/.env.local,/.env.baky rutas similares - En el repositorio, ejecuta
git log --all --oneline -- .envpara ver si alguna vez se subió. Si aparece algo, revoca las claves que contenía - Pega configuración o código en el escáner de filtración de secretos para detectar claves de API o claves privadas escritas en el código (se ejecuta en tu navegador)
- Revisa la lista de variables
NEXT_PUBLIC_/VITE_para asegurarte de que ningún secreto acaba en el JavaScript compilado
La opinión de este sitio: decide a la vez dónde vive .env y cómo revocar sus claves
La mayoría de los incidentes con .env empiezan por un archivo en el sitio equivocado. Lo que hace que el daño se extienda después es no tener un procedimiento fijado para reemplazar las claves.
En este sitio recomendamos que, si usas .env, no solo lo mantengas fuera del directorio público y de Git, sino que dejes escrito de antemano cómo revocar y volver a emitir cada clave que contiene. En producción, pasar a un gestor de secretos en la nube o a variables de entorno cuyos valores no puedan volver a mostrarse reduce todavía más las vías de filtración.
Fuentes (primarias)
- The Twelve-Factor App, «III. Config» (en inglés) — 12factor.net (guardar la configuración en variables de entorno; la prueba del código abierto)
- Documentación de Next.js, «Environment Variables» (en inglés) — nextjs.org (
NEXT_PUBLIC_se incrusta en el JavaScript al compilar; no subir los archivos .env) - Documentación de Vite, «Env Variables and Modes» (en inglés) — vite.dev (las variables
VITE_quedan expuestas al código del cliente) - Unit 42 (Palo Alto Networks), «Leaked Environment Variables Allow Large-Scale Extortion Operation in Cloud Environments» (15 de agosto de 2024, en inglés) — unit42.paloaltonetworks.com
Sigue leyendo
- Incidentes: El .env de Laravel expuesto al mundo · La exposición de variables de entorno en Vercel (en inglés)
- Defensa: Mantener .env fuera de la web pública en hosting compartido · Auditar archivos secretos en directorios públicos · Detener los secretos antes del commit
- Fundamentos: Qué tiene de peligroso .env y las claves de API