Back to blog
Security 10 min read

Your .env file is probably public

Database credentials, API keys, and encryption secrets exposed to anyone who knows where to look. Here's how it happens and how to prevent it.

December 2024 · Updated December 2024

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.example with 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

  1. Set document root to the public directory
  2. Block all dotfiles at the server level
  3. Block common backup file extensions
  4. Disable directory listing
  5. Ensure PHP is processing .php files correctly

Git hygiene

  1. Add .env to .gitignore before your first commit
  2. Use pre-commit hooks to prevent accidental commits
  3. Audit repository history for exposed secrets
  4. Use tools like git-secrets or gitleaks
# 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

  1. Never set APP_DEBUG=true in production
  2. Use environment-specific .env files (.env.production, .env.staging)
  3. Consider using secret management services (AWS Secrets Manager, HashiCorp Vault)
  4. 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:

  1. Fix the exposure immediately - Block access at the server level
  2. Assume compromise - Treat all credentials as leaked
  3. Rotate everything - Database passwords, API keys, APP_KEY, all of it
  4. Check access logs - Look for requests to /.env or similar paths
  5. Audit for damage - Check for unauthorized database access, API usage, etc.
  6. 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.example met 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

  1. Stel de document root in op de public-map
  2. Blokkeer alle dotfiles op serverniveau
  3. Blokkeer veelvoorkomende backup-bestandsextensies
  4. Schakel directory listing uit
  5. Zorg dat PHP .php-bestanden correct verwerkt

Git-hygiëne

  1. Voeg .env toe aan .gitignore voor je eerste commit
  2. Gebruik pre-commit hooks om onbedoelde commits te voorkomen
  3. Controleer repository-geschiedenis op blootgestelde secrets
  4. Gebruik tools zoals git-secrets of gitleaks
# 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

  1. Stel nooit APP_DEBUG=true in productie in
  2. Gebruik omgevingsspecifieke .env-bestanden (.env.production, .env.staging)
  3. Overweeg het gebruik van secret management services (AWS Secrets Manager, HashiCorp Vault)
  4. 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:

  1. Los de blootstelling onmiddellijk op - Blokkeer toegang op serverniveau
  2. Ga uit van compromise - Beschouw alle inloggegevens als gelekt
  3. Roteer alles - Database-wachtwoorden, API-sleutels, APP_KEY, alles
  4. Controleer access logs - Zoek naar verzoeken aan /.env of vergelijkbare paden
  5. Controleer op schade - Controleer op ongeautoriseerde database-toegang, API-gebruik, etc.
  6. 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.example con 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

  1. Establece la raíz del documento en el directorio public
  2. Bloquea todos los dotfiles a nivel del servidor
  3. Bloquea extensiones comunes de archivos de respaldo
  4. Desactiva el listado de directorios
  5. Asegúrate de que PHP esté procesando archivos .php correctamente

Higiene de Git

  1. Añade .env a .gitignore antes de tu primer commit
  2. Usa pre-commit hooks para prevenir commits accidentales
  3. Audita el historial del repositorio en busca de secretos expuestos
  4. Usa herramientas como git-secrets o gitleaks
# 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

  1. Nunca establezcas APP_DEBUG=true en producción
  2. Usa archivos .env específicos por entorno (.env.production, .env.staging)
  3. Considera usar servicios de gestión de secretos (AWS Secrets Manager, HashiCorp Vault)
  4. 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:

  1. Soluciona la exposición inmediatamente - Bloquea el acceso a nivel del servidor
  2. Asume el compromiso - Trata todas las credenciales como filtradas
  3. Rota todo - Contraseñas de base de datos, claves API, APP_KEY, todo
  4. Revisa los logs de acceso - Busca solicitudes a /.env o rutas similares
  5. Audita el daño - Verifica acceso no autorizado a la base de datos, uso de API, etc.
  6. 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.

Related posts

Concerned about your application's security?

A security assessment can identify vulnerabilities before they become breaches. Let's review your setup.

Get in touch