Offenliegende .env-Dateien und geleakte Schlüssel
Eine offenliegende .env-Datei ist eine Konfigurationsdatei — jene mit Ihrem Datenbankpasswort, Ihren Mail-Zugangsdaten und Ihren API-Schlüsseln —, die Ihr Webserver jedem ausliefert, der sie beim Namen verlangt, und ein offenliegender .git-Ordner ist derselbe Unfall mit Ihrer gesamten Quellhistorie im Anhang. Keines von beiden erfordert, dass ein Angreifer irgendetwas bricht: Die Datei liegt schlicht an einem Ort, den der Server veröffentlicht, und eine einzige gewöhnliche GET-Anfrage lädt sie herunter. Dieser Artikel erklärt, wie das passiert — Document-Root-Fehler, statische Hosts, die das Repository selbst ausliefern, Build-Artefakte, die niemand geprüft hat —, was ein Finder in der ersten Stunde mit den Schlüsseln tut, und warum das Löschen der Datei danach der kleinste Teil der Antwort ist. Um Ihre eigene Website jetzt zu prüfen, führen Sie den Scanner für geleakte Secrets aus und lesen Sie mit Ihren Ergebnissen.
Wie eine private Datei öffentlich wird: der Document Root
Jeder Webserver hat einen Document Root: das Verzeichnis, dessen Inhalt per Definition öffentlich ist. Alles, was darin landet — absichtlich oder versehentlich —, kann per URL angefordert werden, ob eine Seite darauf verlinkt oder nicht. Der klassische Unfall ist ein Projekt, das durch Kopieren des gesamten Arbeitsverzeichnisses auf den Server bereitgestellt wird: Der Anwendungscode, der dorthin gehört, kommt zusammen mit der .env-Datei daneben, dem .git-Ordner darin, den Editor-Backup-Kopien, dem Datenbank-Dump, den jemand vor der Migration gemacht hat, und dem Archiv der Version des letzten Monats. Der Server kann diese Dinge nicht auseinanderhalten. Er liefert Dateien aus; die privaten sind auch Dateien.
Framework-Konventionen machen die Falle leicht. Eine .env-Datei gehört eine Ebene über den Document Root oder ganz aus dem bereitgestellten Baum heraus, und die Anwendung sollte sie von der Platte lesen — nie über den Webserver. Aber Entwicklungsserver liefern bereitwillig die Projektwurzel aus, kleine Deployments ziehen alles nach public_html, und eine aus einem Tutorial kopierte Konfiguration kann den Document Root auf das Projekt selbst zeigen lassen. Nichts bricht sichtbar, wenn das passiert, und genau das ist das Problem: Die Website funktioniert perfekt, die Datei ist öffentlich, und der Erste, der es bemerkt, ist derjenige, der /.env anfordert — eine Anfrage, die automatisierte Scanner unablässig gegen jede Website im Internet stellen.
Statische Hosts, ausgelieferte Repositories und Build-Artefakte
Statisches Hosting nimmt die Serverkonfiguration aus der Gleichung und ersetzt sie durch eine einfachere Regel: Was im Veröffentlichungsverzeichnis liegt, wird veröffentlicht. Stellen Sie ein Repository bei einem statischen Host bereit, dessen Ausgabeverzeichnis die Projektwurzel ist, und der Host liefert das Repository treu aus — .git eingeschlossen, falls es in die Ausgabe kopiert wurde. Ein offenliegendes .git ist schlimmer, als es aussieht: Die HEAD-Datei und die Konfiguration beweisen die Struktur, die Objektdateien enthalten jeden je committeten Blob, und mit gewöhnlichen Git-Werkzeugen lässt sich die gesamte Historie rekonstruieren — einschließlich Secrets, die einmal committet und in einem späteren Commit „entfernt“ wurden, was sie aus dem Arbeitsbaum entfernt und sonst nirgends.
Build-Artefakte schaffen eine zweite, leisere Klasse von Offenlegungen. JavaScript-Bundler betten ein, worauf der Code verweist, sodass ein zur Build-Zeit aus einer Umgebungsvariable gelesener API-Schlüssel als literale Zeichenfolge im ausgelieferten Bundle landen kann — öffentlich per Design, von jedem Besucher lesbar und von keiner Berechtigungsprüfung je markiert, weil diese Datei öffentlich sein sollte. Source Maps verschärfen es, indem sie den Originalquelltext neben das Bundle legen. Nichts davon braucht einen falsch konfigurierten Server; es braucht nur einen Build, der nie von außen inspiziert wurde.
Das dritte Muster ist der Überrest: Deployment-Skripte, die ein Archiv ins Webroot entpacken und das Archiv dort liegen lassen, Backup-Plugins, die Dumps in einen per Web erreichbaren Ordner schreiben, ein von einem Editor gespeichertes config.php.bak — das viele Server gerade deshalb als Klartext ausliefern, weil die Erweiterung nicht mehr zum PHP-Handler passt. Jeder Überrest ist eine vollständige Kopie von etwas Privatem, unter einer vorhersehbaren Adresse.
Was Angreifer in der ersten Stunde tun
Die Entdeckung ist automatisiert und konstant. Scanner zählen die bekannten Pfade — Env-Dateien, Git-Innenleben, Konfigurationsnamen, Backup-Erweiterungen — über riesige Adressbereiche auf, und eine frische Offenlegung wird typischerweise binnen Stunden gefunden, oft schneller. Was bei Ihrem Server ankommt, ist eine unauffällige GET-Anfrage, die 200 zurückgibt; es gibt keinen Alarm, weil aus Sicht des Servers nichts Ungewöhnliches geschah. Gehen Sie daher davon aus, dass jede Datei, die einen Tag lang öffentlich war, heruntergeladen wurde, und dass die Beweislast umgekehrt läuft.
Auch die Sichtung ist automatisiert. Eine heruntergeladene .env wird in Sekunden geparst: Datenbank-Zugangsdaten werden gegen jeden erreichbaren Datenbank-Port getestet, Cloud-Schlüssel werden mit einem harmlosen API-Aufruf validiert, der sagt, ob sie leben, Mail-Zugangsdaten werden zum Senden ausprobiert, und Zahlungsschlüssel werden auf ihren Modus geprüft — ein Live-Zahlungsschlüssel und Produktionsdatenbank-Zugangsdaten sind der Hauptgewinn, weil sich jeder direkt in Geld oder Daten umwandeln lässt. Gültige Schlüssel werden rasch benutzt, gehandelt oder gehalten, weil ihre Besitzer sie jederzeit rotieren können; die erste Stunde ist die, in der ein offenliegender Schlüssel am meisten wert ist, und sie wird effizient verbracht.
Warum das Löschen der Datei nicht genügt
Das Löschen der Datei stoppt neue Downloads. Es tut nichts für die Kopien, die bereits existieren: die des Finders, selbstverständlich, aber auch die, die Sie selbst gemacht haben — die von Ihrer CDN oder einem Firmen-Proxy zwischengespeicherte Antwort, der Schnappschuss im Crawl einer Suchmaschine oder eines Archivdienstes, das Bundle, das ein Browser bereits heruntergeladen hat. Bis jeder Cache geleert ist und abläuft, kann die „gelöschte“ Datei noch von Infrastruktur ausgeliefert werden, die Sie kontrollieren, aber zu leeren vergaßen, und die Version außerhalb Ihrer Kontrolle ist für immer außerhalb.
Darum heißt die erste Antwort auf eine bestätigte Offenlegung Rotation, nicht Löschen: Widerrufen Sie die offenliegenden Zugangsdaten und stellen Sie neue aus, damit jede Kopie auf der Welt im selben Augenblick wertlos wird. Rotation hat eine Reihenfolge — Ersatz ausstellen, bereitstellen, prüfen, ob der Dienst funktioniert, dann erst die alten Zugangsdaten widerrufen — und sie erstreckt sich auf alles, was das offenliegende Material aufschließen kann: Eine .git-Offenlegung bedeutet, jedes Secret zu rotieren, das je in der Historie auftauchte, nicht nur die aktuellen, weil die Historie die Offenlegung ist. Lesen Sie danach Ihre Zugriffsprotokolle für die offenliegenden Pfade: Sie sagen Ihnen, ob Sie der Erste waren, der es wusste, und frühere Abrufe machen aus einem Konfigurationsvorfall eine Breach-Untersuchung mit einer ganz anderen Checkliste.
Die Abfrageliste, erklärt — und die Präventions-Checkliste
Ein Scanner wie der Scanner für geleakte Secrets kann Dateien nur beim Namen verlangen, also ist seine Liste die bekannte Menge: /.env und seine Umgebungsvarianten, /.git/HEAD und /.git/config, vertraute Konfigurationsdateinamen, Backup- und Archiv-Erweiterungen und Schlüsseldateinamen — plus die eigenen Skripte der Seite, durchsucht nach schlüsselförmigen Zeichenfolgen. Die ehrliche Grenze schneidet in beide Richtungen: Ein Scanner findet nur, wonach er fragt, und darum bestätigt er einen Fund am Inhalt, nicht am Statuscode. Ein 200, das Ihre Startseite zurückgibt, ist eine Catch-all-Route, kein Leak, und jeder Bericht, der es als eines zählt, bläht sich selbst auf. Das verwandte Lieferkettenrisiko — Skripte, die Sie absichtlich von anderen laden — behandelt Drittanbieter-Skripte und Lieferkettenrisiko.
Prävention ist vor allem Platzierung und eine Schicht Verweigerung. Halten Sie Secrets außerhalb des Document Root und außerhalb der Veröffentlichungsausgabe des Repository; lassen Sie den Server die gefährlichen Namen verweigern, selbst wenn sie dort landen — Deny-Regeln für Dotfiles, Env- und Konfigurations-Erweiterungen, Archive und Schlüsselmaterial, getestet, indem man sie anfordert —; entfernen Sie .git aus Deployment-Artefakten oder blockieren Sie es rundheraus. Fügen Sie in der Pipeline Secret-Scanning in der CI hinzu — bei Commits, damit ein Schlüssel gestoppt wird, bevor er ausgeliefert wird, und am gebauten Artefakt, damit ein gebündelter Schlüssel in der Ausgabe gefangen wird statt von einem Fremden. Scannen Sie schließlich selbst nach Zeitplan und nach jeder Deployment-Änderung: Die Offenlegungen in diesem Artikel sind alle lautlos, und der einzige Weg, von Ihrer zu erfahren, bevor es jemand anderes tut, ist, Ihrem eigenen Server dieselben Fragen zu stellen, die die Scanner stellen.