Nginx-Schwachstelle, die den Tresor von Bitwarden offenlegt
(labs.hakaioffsec.com)- Nginx, ein vielseitiger Webserver mit dominierendem Marktanteil seit 2004
- Fehlkonfigurationen von Nginx können zu Sicherheitslücken und Datenlecks führen
- Vorstellung von NavGix, einem automatisierten Tool zur Erkennung von Schwachstellen in Nginx
- Über diese Schwachstelle kann auf unbeabsichtigte Bereiche von Dateien und Verzeichnissen zugegriffen werden
- Fallstudien zu Bitwarden und Googles HPC Toolkit zeigen die Schwere dieser Schwachstelle
1 Kommentare
Meinungen auf Hacker News
Zur Info: gixy (nginx-Konfigurationsprüfer) erkennt dieses Problem: https://github.com/yandex/gixy/blob/master/docs/en/plugins/a...
Und NixOS führt gixy automatisch für Konfigurationen aus, die darüber erzeugt wurden, und verweigert den System-Build, wenn es Probleme gibt.
$uriin einem 301-Redirect verwendet.Ich frage mich aber, ob es einen besseren Optionen-Sucher gibt. Die Suche über alle Tausenden Optionen fand ich nicht so gut; ich möchte nur ein Paket wie
sshansehen und die dazugehörigen Optionen sehen, aber es werden viel zu viele irrelevante Ergebnisse eingemischt.Vielleicht eine dumme Frage, aber gibt es einen guten Grund, warum nginx erlauben sollte, in URL-Pfaden mit
..in übergeordnete Verzeichnisse zu wechseln? Das wirkt einfach wie ein Verhalten, das nur auf Probleme wartet.Edit: Ich bin etwas verwirrt darüber, was bei der ursprünglichen Schwachstelle passiert. Es scheint, als würde http://localhost/foo../secretfile.txt in etwas wie
/var/www/foo/../secretfile.txtaufgelöst. Warum würde ein nicht verwundbarer Server dann http://localhost/foo/../secretfile.txt nicht genauso auflösen? Ich verstehe nicht, warum..im Pfad nur manchmal funktioniert.In diesem Fall wird ein Teil der URL aufgrund der Art, wie er in der Konfiguration auf das lokale Dateisystem gemappt wird, von nginx als Verzeichnis (http://localhost/foo) interpretiert. Weil das auf ein Verzeichnis zu zeigen scheint, entsteht beim Erstellen des vollständigen Pfads zur angefragten Ressource durch nginx
"${mapped_path}/../secretfile.txt"; aus URL-Sicht ist das unsinnig, im lokalen Dateisystem aber gültig. Eine URL ist nur ein String, keine echten Pfadbestandteile, daher ist auch die Position von Slashes nicht grundsätzlich bedeutsam.Seit es das Web gibt, ist das ein sehr häufiges Problem bei Webservern. URLs direkt auf Dateipfade zu mappen war beliebt, weil es mit einfachen Dateiservern mit Index begann, aber bald wurde daraus eine gemischte Umgebung, in der URLs keine Pfade mehr waren, sondern Anwendungs-IDs: Ein Teil des Pfads gibt die App an, der Rest wird als Parameter oder Argumente betrachtet.
Und generell ergibt es für Dateisystemobjekte meist keinen Sinn,
.oder..in URLs zu respektieren. Meine Apps bereinigen den Request-Pfad, damit er korrekt gemappt wird. Browser behandeln URLs beim Erzeugen relativer Links wie Pfade, daher muss man auch vorsichtig sein, wann und wie man ein abschließendes/verwendet. Serverseitig kann das auf Ressourcen mit anderer Bedeutung verweisen.locationein Flag wieallow_parent_traversal on;zu haben und das zu einem Verhalten zu machen, das man explizit einschalten muss."/foo/bar/.."und verbietet es oder normalisiert es zu"/foo/". Aber"/foo/bar.."ist ein völlig gültiger Dateiname, daher scheint es an solchen Prüfungen vorbeizukommen...in einem Pfad funktioniert, hängt vollständig von den Dateiberechtigungen ab.Nehmen wir in diesem Fall an, dass man vom Web-Indexverzeichnis (
../index.html) bis zum Root-Verzeichnis (/) Leserechte hat. Da man bis zum Root hinabsteigen darf, kann man nun alle von Root aus erreichbaren world-readable Dateien sehen, zum Beispiel/etc/passwd.Stell dir eine dreizinkige Gabel vor: Der Webserver sitzt auf dem ganz rechten Zinken. Wenn der Griff, an dem die Zinken zusammenlaufen, das Dateisystem ist, und man vom rechten Zinken, auf dem der Webserver sitzt, Zugriffsrechte auf die Dateien und Verzeichnisse bis zum Griff hat, kann man nach Erreichen des Griffs auch weiter auf Dateien in den anderen Zinken zugreifen.
Ich verstehe nicht, warum das nicht als nginx-Schwachstelle gilt. Dieses Verhalten ist völlig absurd, scheint keinem nützlichen Zweck zu dienen und ist unmittelbar ausnutzbar.
Man sollte auch bedenken, dass Nginx durch Benchmarks populär wurde, die es als „webskalierbarer“ als Apache2 darstellten.
Mir kam folgender Gedanke: Man könnte im Dateinamen-Parser des Linux-Kernels eine Option ähnlich einer Linux Capability einführen, die die Option
..entfernt.In Web-Apps gibt es seit den Zeiten von Telefonmodems immer wieder Umgehungen, bei denen irgendwie zwei Punkte eingeschleust werden. So wie der Linux-Kernel es bei verschiedenen anderen Klassen von Userspace-Bugs getan hat, ist es jetzt an der Zeit, einen Weg zu finden, dieses Problem auf einen Schlag zu schließen.
RESOLVE_BENEATHunter https://man7.org/linux/man-pages/man2/openat2.2.htmlFreeBSD hat diese Funktion im normalen
openat(2)alsO_RESOLVE_BENEATH.Man kann nginx als separaten Benutzer mit sehr eingeschränkten Rechten ausführen oder in Docker laufen lassen. Zusammen mit regelmäßigen Updates löst das normalerweise 90 % der Sicherheitsprobleme.
/some/../pathsollte nahezu zu 100 % verboten werden. Es gibt keinen sinnvollen Use Case dafür, außer „jemand hat hässlichen Code geschrieben“.../some/pathergibt zumindest gelegentlich Sinn.Allerdings wäre das vermutlich nicht so nützlich, wie man denkt, weil viele Apps
..bereits auflösen, bevor sie es an das Betriebssystem übergeben.Wenn man Dateien aus einem Ordner über das Web ausliefert, muss das Web-Framework sicherstellen, dass man nicht aus dem vorgesehenen öffentlichen Root-Ordner ausbrechen kann. Wenn man das selbst baut, muss man solche und alle möglichen anderen Fälle berücksichtigen.
„Das Google VRP Team zahlte 500 Dollar als Belohnung für das Finden dieser Schwachstelle. Die Auswirkungen auf die Anwendung wurden nicht als schwerwiegend genug für eine höhere Belohnung eingeschätzt“ – offengelegte GCP-Konto-E-Mail-Adressen und private Schlüssel sind nur 500 Dollar wert? Was soll das. Typisch Google.
Zum Glück waren die geleakten Dinge weiterhin verschlüsselt. Wenn selbst ein Unternehmen, das auf diesen Bereich spezialisiert ist, nicht vor Leaks gefeit ist, ist das ehrlich gesagt wohl das Best-Case-Szenario.
Der Titel wurde ziemlich stark bearbeitet. Der Originaltitel lautet Hunting for Nginx Alias Traversals in the wild.
Der HN-Einreichungstitel betont die Bitwarden-Schwachstelle, aber im Artikel wird auch ein Google-Fall behandelt.
Was ist heutzutage die beste Option, wenn man nur zuverlässig und sicher statische Dateien ausliefern will, bei minimalem Ressourcenverbrauch? Früher hätte ich Nginx gewählt, aber aus Sicherheitssicht frage ich mich, ob ein stärker zweckgebundenes Tool mit weniger Konfigurationsmöglichkeiten besser wäre.
Es ist plattformübergreifend, in Rust geschrieben, hat eine einfache Konfiguration und sichere Defaults. Es gibt außerdem ein gehärtetes Container-Image und ein gehärtetes NixOS-Modul.
Caddy würde ich nicht empfehlen. Das offizielle Docker-Image läuft standardmäßig als root [1] und es wird auch keine ordentlich gesandboxte systemd-Unit-Datei bereitgestellt [2].
[1]: https://github.com/caddyserver/caddy-docker/issues/104
[2]: https://github.com/caddyserver/dist/blob/master/init/caddy.s...
Edit: Formulierung geglättet.
file_server-Modul.Vielleicht ist das eine dumme Frage, aber warum hat Bitwarden überhaupt nicht authentifizierte Requests auf
/attachmentserlaubt? Selbst mit dem Nginx-Bug wäre der Request doch fehlgeschlagen, wenn diese URL Authentifizierung erfordert hätte, oder?Trotzdem ist Bitwarden verantwortlich, weil sie über Docker eine gefährliche Konfiguration ausgeliefert haben. Bitwarden scheint das auch anzuerkennen und hat es danach behoben.
Entschuldigung für die dumme Frage. Würde so ein Traversal mit passenden Verzeichnis- und Dateibesitzrechten nicht verhindert?
Wenn nginx nicht als root läuft, wie kann es dann andere Dateien lesen als die, die dem nginx-Benutzer ausdrücklich zugewiesen sind?
go-rwxsetzen, die Gruppe der „static“-Dateien aufwww-datasetzen und nurg+rvergeben – dann kann der Webserver nicht auf die App-Dateien zugreifen.Das ist im Wortsinne App-Hosting 101, und so haben es Leute schon vor 20 Jahren gemacht.
/home.Man muss die Gruppenmitgliedschaften vielleicht etwas genauer anpassen, aber das ist es auf jeden Fall wert.
Vielleicht mache ich da wirklich etwas gründlich falsch. Autsch.
www-datazugewiesen sein. Wenn eine Anwendung sensible Daten erzeugt, sollte man natürlich besser eine 077 umask verwenden.Leider müssen nginx und andere Webserver bei typischen Webanwendungen normalerweise als root laufen, weil sie auf Port 80 oder 443 lauschen müssen. Ports unter 1024 können nur von root geöffnet werden.
Eine ausführlichere Erklärung gibt es hier: https://unix.stackexchange.com/questions/134301/why-does-ngi...