# Zugangsdaten und .env-Dateien richtig schützen

> .env-Datei schützen: richtiger Webroot, Sperren im Webserver, enge Dateirechte, keine Secrets in Git und Austausch nach einem Sicherheitsvorfall.

Quelle: https://phpsos.de/blog/env-dateien-schuetzen/  
Stand: 25.10.2026  
Anbieter: PHP SOS, PHP-Notfallhilfe und Server-Sicherheit. Soforthilfe per WhatsApp: https://wa.me/491736494914?text=Hallo%20PHP%20SOS%2C%20wir%20brauchen%20Hilfe%20mit%20unserem%20PHP-Server.%20Firma%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**Kurz gesagt:** Eine .env-Datei schützen Sie, indem sie gar nicht erst im öffentlich erreichbaren Verzeichnis liegt: Der Webroot zeigt auf einen Unterordner wie `public/`, die Konfiguration liegt eine Ebene darüber. Zusätzlich sperrt der Webserver alle Dateien mit Punkt am Anfang, die Datei ist nur für Eigentümer und PHP-Prozess lesbar und gehört nie ins Git-Repository. Nach einem Einbruch gelten alle Zugangsdaten darin als bekannt und werden ausgetauscht.

## Die Datei mit den Schlüsseln zum Haus

Moderne PHP-Projekte legen ihre Geheimnisse gern in einer Datei namens `.env` ab: Datenbankpasswort, Zugang zum Mailserver, API-Schlüssel für Zahlungs- und Versanddienste, der Schlüssel, mit dem die Anwendung Cookies signiert. Frameworks wie Laravel und Symfony nutzen dieses Muster, viele Eigenentwicklungen haben es übernommen.

Die Idee ist gut: Konfiguration und Code sind getrennt, und jede Umgebung bekommt eigene Werte. Gefährlich wird es, wenn die Datei im falschen Verzeichnis landet. Liegt sie im Webroot und sperrt der Webserver sie nicht, genügt ein einziger Aufruf im Browser, um alle Zugänge auf einmal zu lesen.

Dazu kommen Varianten mit anderen Namen: `.env.local`, `.env.production`, `config.local.php` oder Dateien mit Zugangsdaten zu Speicherdiensten. Was hier für `.env` beschrieben ist, gilt für alle Dateien, in denen Geheimnisse stehen.

Solche Dateien werden laufend von automatisierten Scannern gesucht. Das ist keine Spezialität einzelner Angreifer, sondern Grundrauschen im Internet, ähnlich wie die Massenscans nach ungepatchten PHP-Versionen.

## Wo die .env-Datei liegen sollte

Die wirksamste Maßnahme ist strukturell: Der Webserver darf nur den Ordner ausliefern, der wirklich öffentlich sein soll. In Laravel und Symfony ist das der Ordner `public/`. Alles andere, also Code, Konfiguration, Logs und `.env`, liegt darüber und ist über HTTP gar nicht adressierbar.

```text
/srv/www/shop/
├── .env              ← nicht erreichbar
├── config/
├── src/
├── vendor/
└── public/           ← einziger Webroot
    ├── index.php
    └── assets/
```

In der Praxis zeigt der Webroot trotzdem oft auf das Projektverzeichnis selbst, etwa weil ein Hosting-Panel das so vorgibt oder weil beim Umzug ein Pfad nicht angepasst wurde. Prüfen Sie deshalb in der Webserver-Konfiguration oder im Panel, wohin `root` beziehungsweise `DocumentRoot` zeigt.

## .env-Datei schützen: Sperre im Webserver als zweite Linie

Lässt sich der Webroot nicht ändern, oder wollen Sie eine zusätzliche Absicherung, sperren Sie versteckte Dateien im Webserver. Der Ordner `.well-known` muss dabei erreichbar bleiben, weil er unter anderem für die Ausstellung von Zertifikaten genutzt wird.

```nginx
# Alle Dateien und Ordner mit Punkt am Anfang sperren, außer .well-known
location ~ /\.(?!well-known/) {
    deny all;
    return 404;
}
```

```apache
# Dateien mit Punkt am Anfang sperren
<FilesMatch "^\.">
    Require all denied
</FilesMatch>
```

Eine Antwort mit 404 statt 403 verrät nicht, dass die Datei existiert. Ob die Sperre wirkt, prüfen Sie von außen:

```bash
# Erwartet: 403 oder 404, niemals 200
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.env
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.env.example
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.env.bak
```

Die letzten beiden Zeilen sind kein Zufall: Kopien wie `.env.bak` oder `.env.old` entstehen bei Wartungsarbeiten und werden oft vergessen. Mehr zu solchen Überbleibseln steht in [Backup-Dateien im Webroot](https://phpsos.de/blog/backup-dateien-im-webroot/).

## Rechte, Git und der Umgang mit Kopien

Auch außerhalb des Webroots gilt das Prinzip der geringsten Rechte. Eine bewährte Aufteilung:

1. **Eigentümer** ist der Deploy-Benutzer, nicht der PHP-Prozess.
2. **Gruppe** ist die Gruppe des PHP-FPM-Pools, die nur lesen darf; Rechte `640`.
3. **Kein Schreibzugriff** für den PHP-Prozess. Eine Anwendung muss ihre eigenen Zugangsdaten nicht ändern können.
4. **Keine echten Werte im Repository:** Nur `.env.example` mit Platzhaltern wird eingecheckt, die echte Datei steht in `.gitignore`.
5. **Getrennte Werte je Umgebung:** Entwicklung, Staging und Produktion nutzen unterschiedliche Zugänge, damit ein Leck in einer Testumgebung nicht die Produktion öffnet.

```bash
chown deploy:shop-php /srv/www/shop/.env
chmod 640 /srv/www/shop/.env
# Prüfen, ob die Datei jemals eingecheckt wurde
git log --all --oneline -- .env
```

Achten Sie auch auf Fehlerseiten. Frameworks zeigen im Debug-Modus teils Umgebungsvariablen und Konfigurationswerte an; auf einem Produktivsystem muss dieser Modus abgeschaltet sein. Prüfen Sie das nach jedem Deployment, denn ein falscher Wert in der `.env` selbst kann ihn wieder einschalten.

Liefert der letzte Befehl Treffer, stehen die Zugangsdaten in der Git-Historie und gelten als offengelegt, auch wenn die Datei heute fehlt. Warum das besonders heikel ist, wenn der `.git`-Ordner auf dem Server liegt, beschreibt [Öffentlicher .git-Ordner: Ein unterschätztes Datenleck](https://phpsos.de/blog/git-ordner-oeffentlich/). Grundsätzliches zu Rechten erklärt der Ratgeber [Dateirechte auf dem Webserver](https://phpsos.de/ratgeber/dateirechte-webserver/).

> **Wichtig:**
> Testdateien mit `phpinfo()` zeigen Umgebungsvariablen an. Wer Geheimnisse als Umgebungsvariablen übergibt, verrät sie über eine vergessene Testdatei. Hintergründe stehen in [phpinfo()-Dateien: Warum sie verschwinden müssen](https://phpsos.de/blog/phpinfo-dateien-entfernen/).

## Nach einem Einbruch: Zugangsdaten austauschen

Keine Sperre schützt vor einem Angreifer, der bereits Code auf dem Server ausführt. Ein PHP-Prozess muss seine Konfiguration lesen können, also kann eingeschleuster Code im selben Prozess das auch. Nach PHP2Shell gilt deshalb: Kann ein Einbruch nicht ausgeschlossen werden, sind alle Zugangsdaten auf dem Server als bekannt zu behandeln.

Ein geordneter Austausch umfasst Datenbankpasswörter, Mail- und SMTP-Zugänge, API-Schlüssel externer Dienste, Signaturschlüssel der Anwendung und Zugänge zu Speicherdiensten. Reihenfolge und Zeitpunkt sollten geplant sein: Wer zuerst austauscht und dann den Server bereinigt, gibt dem Angreifer die neuen Werte womöglich gleich mit.

Den Schaden eines Lecks begrenzen Sie schon vorher, indem jedes Geheimnis nur so viel darf wie nötig. Der Datenbankbenutzer der Website braucht keine Rechte auf andere Datenbanken. API-Schlüssel externer Dienste lassen sich bei vielen Anbietern auf einzelne Funktionen oder Absenderadressen beschränken, etwa Sendungen anlegen, aber keine Auszahlungen veranlassen. Und jede Anwendung erhält eigene Zugänge, statt dass mehrere Websites dasselbe Mailkonto oder denselben Schlüssel teilen. Dann betrifft ein Leck einen klar abgegrenzten Bereich, und der Austausch bleibt überschaubar.

In Container-Umgebungen gehört die `.env`-Datei weder ins Image noch in eine öffentlich erreichbare Registry. Schließen Sie sie per `.dockerignore` aus und übergeben Sie Geheimnisse erst zur Laufzeit über die Mechanismen der Plattform.

Langfristig lohnt der Blick auf zentrale Secret-Speicher, wie OWASP sie empfiehlt: Geheimnisse an einem Ort, mit Zugriffsprotokoll, regelmäßigem Austausch und möglichst kurzer Gültigkeit.

## Wie hilft PHP SOS konkret?

- Wir prüfen von außen, ob Konfigurationsdateien, Kopien und versteckte Dateien Ihrer Websites abrufbar sind.
- Wir stellen Webroot, Webserver-Sperren und Dateirechte so um, dass Geheimnisse nicht mehr über HTTP erreichbar sind.
- Wir prüfen Repositories und Deployments auf eingecheckte Zugangsdaten.
- Nach einem Vorfall planen und begleiten wir den Austausch aller betroffenen Zugänge in der richtigen Reihenfolge.

Diese Arbeiten sind Teil unserer [Server-Härtung für PHP-Webserver](https://phpsos.de/leistungen/server-haertung/).


## Häufige Fragen

**Ist eine .env-Datei im Webroot automatisch öffentlich?**  
Nicht automatisch, aber häufig. Ob sie abrufbar ist, hängt von der Webserver-Konfiguration ab. Viele Standardkonfigurationen schützen nur .htaccess-Dateien, nicht andere Dateien mit Punkt am Anfang. Ein Test mit curl schafft Klarheit.

**Sind Umgebungsvariablen sicherer als eine .env-Datei?**  
Nicht grundsätzlich. OWASP weist darauf hin, dass Umgebungsvariablen für alle Prozesse des Benutzers lesbar sind und in Logs oder Speicherabbildern auftauchen können. Sie vermeiden aber eine Datei im Webroot. Besser sind zentrale Secret-Speicher, wo die Umgebung sie unterstützt.

**Was tun, wenn die .env-Datei abrufbar war?**  
Alle darin enthaltenen Zugangsdaten als bekannt betrachten und austauschen: Datenbank, Mail, APIs, Zahlungsdienste, Schlüssel der Anwendung. Danach in den Zugriffsprotokollen prüfen, ob die Datei abgerufen wurde, und bei personenbezogenen Daten den Datenschutzbeauftragten einbeziehen.

**Gehört die .env-Datei ins Git-Repository?**  
Nein. Ins Repository gehört höchstens eine Vorlage ohne echte Werte, etwa .env.example. Die echte Datei wird über .gitignore ausgeschlossen und auf dem Server getrennt bereitgestellt.

**Kann phpinfo() Zugangsdaten verraten?**  
Ja. phpinfo() zeigt unter anderem Umgebungsvariablen und Servervariablen an. Liegen Geheimnisse dort, werden sie mit ausgegeben. Testdateien mit phpinfo() gehören deshalb nie auf ein erreichbares System.

## Quellen

- [OWASP Secrets Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html)
- [Nginx-Dokumentation](https://nginx.org/en/docs/)
- [Apache HTTP Server: Dokumentation](https://httpd.apache.org/docs/)
