TL;DR
Environment files get exposed through misconfigured web servers, accidental git commits, backup files, and debug pages. Test your own sites right now: try accessing yourdomain.com/.env. If you see content, you have a critical security issue.
Environment-bestanden worden blootgesteld door verkeerd geconfigureerde webservers, onbedoelde git commits, backup-bestanden en debug-pagina's. Test je eigen sites nu: probeer yourdomain.com/.env te openen. Als je inhoud ziet, heb je een kritiek beveiligingsprobleem.
Los archivos de entorno se exponen a través de servidores web mal configurados, commits de git accidentales, archivos de respaldo y páginas de depuración. Prueba tus propios sitios ahora mismo: intenta acceder a tudominio.com/.env. Si ves contenido, tienes un problema crítico de seguridad.
The uncomfortable reality
I've been doing security assessments for years, and one of the most common findings is exposed environment files. Not in small, amateur projects - in production applications handling real customer data and processing real payments.
The .env file is the skeleton key to your application. It typically contains:
- Database credentials (full access to all your data)
- API keys for third-party services (Stripe, AWS, SendGrid)
- APP_KEY - Laravel's encryption secret
- Mail server credentials
- Redis/cache passwords
- JWT secrets and OAuth tokens
If an attacker gets this file, they don't need to hack anything else. They have the keys to everything.
How .env files get exposed
1. Misconfigured web servers
This is the most common scenario. Your web server should only serve files from the public directory, but misconfigurations can expose the entire project root.
# WRONG - serves from project root
server {
root /var/www/myapp;
index index.php;
}
# CORRECT - serves from public directory
server {
root /var/www/myapp/public;
index index.php;
}
Even with the correct root, some configurations forget to block dotfiles:
# Add this to your nginx config
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
For Apache, your .htaccess should include:
# Block access to dotfiles
<FilesMatch "^\.">
Order allow,deny
Deny from all
</FilesMatch>
2. Git commits
"I'll just commit this quickly and fix it later." Famous last words.
Once a file is committed to git, it lives in the repository history forever. Even if you remove it in the next commit, anyone with access to the repository can see it in the history.
# Finding .env in git history
git log --all --full-history -- .env
git show <commit-hash>:.env
The fix isn't just removing the file - you need to rotate all credentials and either rewrite git history (if the repo is private) or consider those credentials permanently compromised.
3. Backup files
Editors and deployment scripts often create backup files. I've found these exposed:
.env.backup.env.bak.env.old.env.save.env~(vim backup).env.swp(vim swap file).env.examplewith real values (yes, really)
Your server configuration needs to block all variations, not just the exact filename.
4. Debug pages and error messages
Laravel's debug mode is a goldmine for attackers. When APP_DEBUG=true in production, exception pages display:
- Full environment variable dumps
- Database queries with bound parameters
- File paths and stack traces
- Server configuration details
Critical rule
Never run APP_DEBUG=true in production. If you need debugging in production, use proper logging and monitoring tools like Sentry, Bugsnag, or Laravel Telescope (with authentication).
5. Source code disclosure
PHP misconfigurations can serve source files as plain text. If PHP isn't processing .php files correctly, attackers can read your configuration files directly:
# Testing for PHP source disclosure
curl -s "https://target.com/config/database.php" | head -20
Detection methods
Test your own sites
Run these checks against your production sites right now:
# Direct .env access
curl -s -o /dev/null -w "%{http_code}" https://yoursite.com/.env
# Common backup variations
for ext in "" ".backup" ".bak" ".old" ".save" ".example" "~"; do
echo -n ".env$ext: "
curl -s -o /dev/null -w "%{http_code}" "https://yoursite.com/.env$ext"
echo
done
# Git exposure
curl -s -o /dev/null -w "%{http_code}" https://yoursite.com/.git/config
Any response code other than 403 or 404 warrants investigation.
Automated scanning
Include environment file checks in your deployment pipeline:
# GitHub Actions example
- name: Security Check - Env Exposure
run: |
response=$(curl -s -o /dev/null -w "%{http_code}" ${{ secrets.PRODUCTION_URL }}/.env)
if [ "$response" != "403" ] && [ "$response" != "404" ]; then
echo "CRITICAL: .env file may be exposed!"
exit 1
fi
Prevention checklist
Server configuration
- Set document root to the
publicdirectory - Block all dotfiles at the server level
- Block common backup file extensions
- Disable directory listing
- Ensure PHP is processing .php files correctly
Git hygiene
- Add
.envto.gitignorebefore your first commit - Use pre-commit hooks to prevent accidental commits
- Audit repository history for exposed secrets
- Use tools like
git-secretsorgitleaks
# Install git-secrets
brew install git-secrets
# Configure for your repo
git secrets --install
git secrets --register-aws
# Scan history for secrets
git secrets --scan-history
Application settings
- Never set
APP_DEBUG=truein production - Use environment-specific .env files (.env.production, .env.staging)
- Consider using secret management services (AWS Secrets Manager, HashiCorp Vault)
- Rotate credentials regularly, especially after any potential exposure
What to do if you're exposed
If you've discovered your .env file is publicly accessible:
- Fix the exposure immediately - Block access at the server level
- Assume compromise - Treat all credentials as leaked
- Rotate everything - Database passwords, API keys, APP_KEY, all of it
- Check access logs - Look for requests to /.env or similar paths
- Audit for damage - Check for unauthorized database access, API usage, etc.
- Implement monitoring - Alert on any future access attempts to sensitive paths
The bigger picture
Environment file exposure is a symptom of a larger problem: security isn't built into the development process. When deployments are rushed, when configuration is treated as an afterthought, when security reviews happen (if at all) at the end of a project - this is what happens.
The fix isn't just blocking /.env. It's building security into your workflow from day one. Automated checks. Secure defaults. Regular audits. A culture where "it works" isn't good enough - it needs to work securely.
Need a security assessment for your PHP application? I can help identify vulnerabilities before attackers do. Let's talk.
De ongemakkelijke realiteit
Ik doe al jaren beveiligingsbeoordelingen, en een van de meest voorkomende bevindingen is blootgestelde environment-bestanden. Niet in kleine, amateurprojecten - maar in productieapplicaties die echte klantgegevens verwerken en echte betalingen afhandelen.
Het .env-bestand is de loper van je applicatie. Het bevat meestal:
- Database-inloggegevens (volledige toegang tot al je gegevens)
- API-sleutels voor externe services (Stripe, AWS, SendGrid)
- APP_KEY - Laravel's encryptiesleutel
- Mailserver-inloggegevens
- Redis/cache-wachtwoorden
- JWT-secrets en OAuth-tokens
Als een aanvaller dit bestand in handen krijgt, hoeven ze niets anders te hacken. Ze hebben de sleutels tot alles.
Hoe .env-bestanden worden blootgesteld
1. Verkeerd geconfigureerde webservers
Dit is het meest voorkomende scenario. Je webserver zou alleen bestanden uit de public-map moeten serveren, maar verkeerde configuraties kunnen de hele projectroot blootstellen.
# FOUT - serveert vanuit projectroot
server {
root /var/www/myapp;
index index.php;
}
# CORRECT - serveert vanuit public directory
server {
root /var/www/myapp/public;
index index.php;
}
Zelfs met de juiste root vergeten sommige configuraties dotfiles te blokkeren:
# Voeg dit toe aan je nginx config
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
Voor Apache moet je .htaccess dit bevatten:
# Blokkeer toegang tot dotfiles
<FilesMatch "^\.">
Order allow,deny
Deny from all
</FilesMatch>
2. Git commits
"Ik commit dit even snel en fix het later wel." Beroemde laatste woorden.
Zodra een bestand naar git is gecommit, blijft het voor altijd in de repository-geschiedenis staan. Zelfs als je het in de volgende commit verwijdert, kan iedereen met toegang tot de repository het in de geschiedenis zien.
# .env zoeken in git-geschiedenis
git log --all --full-history -- .env
git show <commit-hash>:.env
De oplossing is niet alleen het bestand verwijderen - je moet alle inloggegevens roteren en ofwel de git-geschiedenis herschrijven (als de repo privé is) of deze inloggegevens als permanent gecompromitteerd beschouwen.
3. Backup-bestanden
Editors en deployment-scripts maken vaak backup-bestanden. Ik heb deze blootgesteld gevonden:
.env.backup.env.bak.env.old.env.save.env~(vim backup).env.swp(vim swap-bestand).env.examplemet echte waarden (ja, echt)
Je serverconfiguratie moet alle variaties blokkeren, niet alleen de exacte bestandsnaam.
4. Debug-pagina's en foutmeldingen
Laravel's debug-modus is een goudmijn voor aanvallers. Wanneer APP_DEBUG=true in productie staat, tonen exception-pagina's:
- Volledige dumps van environment-variabelen
- Database-queries met gebonden parameters
- Bestandspaden en stack traces
- Serverconfiguratie-details
Kritieke regel
Draai nooit APP_DEBUG=true in productie. Als je debugging in productie nodig hebt, gebruik dan goede logging- en monitoring-tools zoals Sentry, Bugsnag, of Laravel Telescope (met authenticatie).
5. Source code disclosure
PHP-misconfiguraties kunnen bronbestanden als platte tekst serveren. Als PHP .php-bestanden niet correct verwerkt, kunnen aanvallers je configuratiebestanden direct lezen:
# Testen op PHP source disclosure
curl -s "https://target.com/config/database.php" | head -20
Detectiemethoden
Test je eigen sites
Voer deze controles nu uit op je productiesites:
# Directe .env-toegang
curl -s -o /dev/null -w "%{http_code}" https://yoursite.com/.env
# Veelvoorkomende backup-variaties
for ext in "" ".backup" ".bak" ".old" ".save" ".example" "~"; do
echo -n ".env$ext: "
curl -s -o /dev/null -w "%{http_code}" "https://yoursite.com/.env$ext"
echo
done
# Git-blootstelling
curl -s -o /dev/null -w "%{http_code}" https://yoursite.com/.git/config
Elke response-code anders dan 403 of 404 vereist onderzoek.
Geautomatiseerd scannen
Neem environment-bestandscontroles op in je deployment-pipeline:
# GitHub Actions-voorbeeld
- name: Security Check - Env Exposure
run: |
response=$(curl -s -o /dev/null -w "%{http_code}" ${{ secrets.PRODUCTION_URL }}/.env)
if [ "$response" != "403" ] && [ "$response" != "404" ]; then
echo "CRITICAL: .env file may be exposed!"
exit 1
fi
Preventiechecklist
Serverconfiguratie
- Stel de document root in op de
public-map - Blokkeer alle dotfiles op serverniveau
- Blokkeer veelvoorkomende backup-bestandsextensies
- Schakel directory listing uit
- Zorg dat PHP .php-bestanden correct verwerkt
Git-hygiëne
- Voeg
.envtoe aan.gitignorevoor je eerste commit - Gebruik pre-commit hooks om onbedoelde commits te voorkomen
- Controleer repository-geschiedenis op blootgestelde secrets
- Gebruik tools zoals
git-secretsofgitleaks
# Installeer git-secrets
brew install git-secrets
# Configureer voor je repo
git secrets --install
git secrets --register-aws
# Scan geschiedenis voor secrets
git secrets --scan-history
Applicatie-instellingen
- Stel nooit
APP_DEBUG=truein productie in - Gebruik omgevingsspecifieke .env-bestanden (.env.production, .env.staging)
- Overweeg het gebruik van secret management services (AWS Secrets Manager, HashiCorp Vault)
- Roteer inloggegevens regelmatig, vooral na mogelijke blootstelling
Wat te doen als je bent blootgesteld
Als je hebt ontdekt dat je .env-bestand publiek toegankelijk is:
- Los de blootstelling onmiddellijk op - Blokkeer toegang op serverniveau
- Ga uit van compromise - Beschouw alle inloggegevens als gelekt
- Roteer alles - Database-wachtwoorden, API-sleutels, APP_KEY, alles
- Controleer access logs - Zoek naar verzoeken aan /.env of vergelijkbare paden
- Controleer op schade - Controleer op ongeautoriseerde database-toegang, API-gebruik, etc.
- Implementeer monitoring - Waarschuw bij toekomstige toegangspogingen tot gevoelige paden
Het grotere plaatje
Blootstelling van environment-bestanden is een symptoom van een groter probleem: beveiliging is niet ingebouwd in het ontwikkelproces. Wanneer deployments gehaast worden, wanneer configuratie als een bijgedachte wordt behandeld, wanneer beveiligingsreviews (als ze al plaatsvinden) aan het einde van een project gebeuren - dit is wat er gebeurt.
De oplossing is niet alleen /.env blokkeren. Het is beveiliging vanaf dag één in je workflow inbouwen. Geautomatiseerde controles. Veilige standaarden. Regelmatige audits. Een cultuur waar "het werkt" niet goed genoeg is - het moet veilig werken.
Heb je een beveiligingsbeoordeling nodig voor je PHP-applicatie? Ik kan helpen kwetsbaarheden te identificeren voordat aanvallers dat doen. Laten we praten.
La realidad incómoda
Llevo años realizando evaluaciones de seguridad, y uno de los hallazgos más comunes son los archivos de entorno expuestos. No en proyectos pequeños y amateur, sino en aplicaciones de producción que manejan datos reales de clientes y procesan pagos reales.
El archivo .env es la llave maestra de tu aplicación. Normalmente contiene:
- Credenciales de base de datos (acceso completo a todos tus datos)
- Claves API para servicios de terceros (Stripe, AWS, SendGrid)
- APP_KEY - el secreto de encriptación de Laravel
- Credenciales del servidor de correo
- Contraseñas de Redis/caché
- Secretos JWT y tokens OAuth
Si un atacante obtiene este archivo, no necesita hackear nada más. Tiene las llaves de todo.
Cómo se exponen los archivos .env
1. Servidores web mal configurados
Este es el escenario más común. Tu servidor web solo debería servir archivos desde el directorio public, pero las configuraciones incorrectas pueden exponer toda la raíz del proyecto.
# INCORRECTO - sirve desde la raíz del proyecto
server {
root /var/www/myapp;
index index.php;
}
# CORRECTO - sirve desde el directorio public
server {
root /var/www/myapp/public;
index index.php;
}
Incluso con la raíz correcta, algunas configuraciones olvidan bloquear los dotfiles:
# Añade esto a tu configuración de nginx
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
Para Apache, tu .htaccess debería incluir:
# Bloquear acceso a dotfiles
<FilesMatch "^\.">
Order allow,deny
Deny from all
</FilesMatch>
2. Commits de Git
"Solo haré commit de esto rápidamente y lo arreglaré después." Famosas últimas palabras.
Una vez que un archivo se commitea a git, vive en el historial del repositorio para siempre. Incluso si lo eliminas en el siguiente commit, cualquiera con acceso al repositorio puede verlo en el historial.
# Encontrar .env en el historial de git
git log --all --full-history -- .env
git show <commit-hash>:.env
La solución no es solo eliminar el archivo - necesitas rotar todas las credenciales y reescribir el historial de git (si el repositorio es privado) o considerar esas credenciales permanentemente comprometidas.
3. Archivos de respaldo
Los editores y scripts de despliegue a menudo crean archivos de respaldo. He encontrado estos expuestos:
.env.backup.env.bak.env.old.env.save.env~(respaldo de vim).env.swp(archivo swap de vim).env.examplecon valores reales (sí, en serio)
Tu configuración del servidor necesita bloquear todas las variaciones, no solo el nombre exacto del archivo.
4. Páginas de depuración y mensajes de error
El modo de depuración de Laravel es una mina de oro para los atacantes. Cuando APP_DEBUG=true en producción, las páginas de excepción muestran:
- Volcados completos de variables de entorno
- Consultas de base de datos con parámetros vinculados
- Rutas de archivos y stack traces
- Detalles de configuración del servidor
Regla crítica
Nunca ejecutes APP_DEBUG=true en producción. Si necesitas depuración en producción, usa herramientas adecuadas de logging y monitoreo como Sentry, Bugsnag, o Laravel Telescope (con autenticación).
5. Divulgación de código fuente
Las configuraciones incorrectas de PHP pueden servir archivos fuente como texto plano. Si PHP no está procesando archivos .php correctamente, los atacantes pueden leer tus archivos de configuración directamente:
# Probar divulgación de código PHP
curl -s "https://target.com/config/database.php" | head -20
Métodos de detección
Prueba tus propios sitios
Ejecuta estas verificaciones en tus sitios de producción ahora mismo:
# Acceso directo a .env
curl -s -o /dev/null -w "%{http_code}" https://yoursite.com/.env
# Variaciones comunes de respaldo
for ext in "" ".backup" ".bak" ".old" ".save" ".example" "~"; do
echo -n ".env$ext: "
curl -s -o /dev/null -w "%{http_code}" "https://yoursite.com/.env$ext"
echo
done
# Exposición de Git
curl -s -o /dev/null -w "%{http_code}" https://yoursite.com/.git/config
Cualquier código de respuesta diferente de 403 o 404 requiere investigación.
Escaneo automatizado
Incluye verificaciones de archivos de entorno en tu pipeline de despliegue:
# Ejemplo de GitHub Actions
- name: Security Check - Env Exposure
run: |
response=$(curl -s -o /dev/null -w "%{http_code}" ${{ secrets.PRODUCTION_URL }}/.env)
if [ "$response" != "403" ] && [ "$response" != "404" ]; then
echo "CRITICAL: .env file may be exposed!"
exit 1
fi
Lista de verificación de prevención
Configuración del servidor
- Establece la raíz del documento en el directorio
public - Bloquea todos los dotfiles a nivel del servidor
- Bloquea extensiones comunes de archivos de respaldo
- Desactiva el listado de directorios
- Asegúrate de que PHP esté procesando archivos .php correctamente
Higiene de Git
- Añade
.enva.gitignoreantes de tu primer commit - Usa pre-commit hooks para prevenir commits accidentales
- Audita el historial del repositorio en busca de secretos expuestos
- Usa herramientas como
git-secretsogitleaks
# Instalar git-secrets
brew install git-secrets
# Configurar para tu repositorio
git secrets --install
git secrets --register-aws
# Escanear historial en busca de secretos
git secrets --scan-history
Configuración de la aplicación
- Nunca establezcas
APP_DEBUG=trueen producción - Usa archivos .env específicos por entorno (.env.production, .env.staging)
- Considera usar servicios de gestión de secretos (AWS Secrets Manager, HashiCorp Vault)
- Rota las credenciales regularmente, especialmente después de cualquier exposición potencial
Qué hacer si estás expuesto
Si has descubierto que tu archivo .env es públicamente accesible:
- Soluciona la exposición inmediatamente - Bloquea el acceso a nivel del servidor
- Asume el compromiso - Trata todas las credenciales como filtradas
- Rota todo - Contraseñas de base de datos, claves API, APP_KEY, todo
- Revisa los logs de acceso - Busca solicitudes a /.env o rutas similares
- Audita el daño - Verifica acceso no autorizado a la base de datos, uso de API, etc.
- Implementa monitoreo - Alerta sobre futuros intentos de acceso a rutas sensibles
El panorama general
La exposición de archivos de entorno es un síntoma de un problema mayor: la seguridad no está integrada en el proceso de desarrollo. Cuando los despliegues son apresurados, cuando la configuración se trata como algo secundario, cuando las revisiones de seguridad ocurren (si es que ocurren) al final de un proyecto - esto es lo que sucede.
La solución no es solo bloquear /.env. Es integrar la seguridad en tu flujo de trabajo desde el primer día. Verificaciones automatizadas. Valores predeterminados seguros. Auditorías regulares. Una cultura donde "funciona" no es suficiente - necesita funcionar de forma segura.
¿Necesitas una evaluación de seguridad para tu aplicación PHP? Puedo ayudarte a identificar vulnerabilidades antes que los atacantes. Hablemos.