Stell dir eine Werkstatt vor, in der seit Juni ein fertiges Ersatzteil auf dem Regal liegt, beschriftet, geprüft, mit Rechnung. Nur eingebaut hat es niemand, weil das Auto nicht in die Werkstatt kam. So ging es dem wichtigsten Stück Code in Nginx Proxy Manager: Der Fix für eine Lücke, über die ein angemeldeter Benutzer Befehle auf dem Server ausführen konnte, wurde am 07-06-2026 in den Quellcode übernommen. Ein fertiges Image dazu gab es bis gestern nicht. Version 2.16.0 vom 24-09-2026 ist das erste Release, das ihn enthält, nach 109 Tagen im Regal.

Drei Lücken, die 2.16.0 schließt
Die größte trägt die Nummer CVE-2026-40519 und betrifft laut GitHub-Advisory jede Version von 2.9.14 bis 2.15.1, also auch die, die bis gestern aktuell war. Der Fehler saß in der Funktion, die beim Start des Backends die Zugangsdaten für DNS-Anbieter in Dateien schreibt. Das Feld dafür landete ohne saubere Prüfung in einem Shell-Befehl, und die Reihenfolge der Schutzmaßnahmen war verkehrt: Der Autor des Fixes, Yasha-ops, schreibt, dass Backslashes erst nach den Anführungszeichen entschärft wurden, „breaking the protection and allowing injection“. Wer also in NPM ein Zertifikat mit DNS-Challenge anlegen darf, konnte in dieses Feld einen Befehl schreiben, der beim nächsten Neustart als root im Container lief. Schweregrad hoch, 7,7 von 10.
Die Einordnung, die im Advisory steht und die ich für die wichtigste halte: Der Angreifer braucht ein Konto in NPM mit dem Recht, Zertifikate zu verwalten. Im Homelab mit einem einzigen Admin-Konto heißt das, er muss schon drin sein. Das macht die Lücke nicht harmlos, aber es sagt dir, wo die Tür ist: bei Port 81. Wer die Verwaltungsoberfläche nie ins Internet gestellt hat, hatte das Problem hinter einer verschlossenen Tür. Wer sie freigegeben hat, hatte es hinter einer Tür mit Passwort, und Passwörter werden erraten, geleakt und wiederverwendet. Ich würde das Update trotzdem allen ans Herz legen, weil die Reparatur nicht nur die Reihenfolge der Anführungszeichen richtet: Der Shell-Befehl ist ganz weg, die Datei wird jetzt direkt aus Node geschrieben. Das ist die Art Fix, die den Fehler nicht flickt, sondern die Fehlerquelle abschafft.
Was mich an der Geschichte stört, ist nicht der Fehler. Es ist der Kalender. Das Issue dazu wurde am 12-04-2026 eröffnet, der Fix am 07-06-2026 übernommen, vier Tage nach dem Release 2.15.1. Dann kam 113 Tage kein Release. Das Projekt hat 34.000 Sterne und einen Hauptentwickler, und ich verstehe, dass Freizeit endlich ist. Aber ein Sicherheitsfix, der im Hauptzweig liegt, hilft niemandem, der ein Image zieht. Genau das tun alle, denn Docker ist laut FAQ der einzige unterstützte Weg.
Die zweite Lücke ist von der leisen Sorte, und sie betrifft die Zwei-Faktor-Anmeldung. Wer sie in NPM einschaltete, bekam einen QR-Code zum Scannen. Den erzeugte die Oberfläche bis 2.15.1 nicht selbst, sondern ließ ihn von einem fremden Dienst im Internet zeichnen, api.qrserver.com. Dazu schickte sie ihm den kompletten otpauth://-Link, und in dem steckt das Geheimnis, aus dem deine Authenticator-App die sechsstelligen Codes rechnet. Der Entwickler vgoer hat das gefunden und durch eine lokale Bibliothek ersetzt; in seinem Pull Request steht der Satz, den man zweimal lesen muss: „the TOTP secret for every user enabling 2FA was transmitted in plaintext to an external service“. Ob der Dienst die Links gespeichert hat, weiß niemand. Mein Urteil: Wer 2FA vor 2.16.0 eingerichtet hat, schaltet es nach dem Update einmal aus und wieder ein, damit ein frisches Geheimnis entsteht, das nie das Haus verlassen hat. Fünf Minuten, und ein Fragezeichen weniger.
Die dritte kommt von jmrplens und antwortet auf ein Issue, das jeder nachvollziehen kann: Änderst du dein Passwort, bleiben Sitzungen, die mit dem alten Passwort geöffnet wurden, bis zu 24 Stunden gültig. Ein Angreifer mit deinem alten Passwort blieb also einen Tag lang drin, obwohl du ihn ausgesperrt hattest. Seit 2.16.0 merkt sich NPM den Zeitpunkt der Passwortänderung und weist ältere Anmeldungen ab. Dazu kommen zwei Handgriffe, die keine Nummer bekommen haben, aber in dieselbe Richtung gehen: Die Zugangsdaten für DNS-Anbieter werden nach dem Certbot-Lauf wieder von der Platte gelöscht, und private Schlüssel bekommen die Rechte 0600, also lesbar nur für den Besitzer.
Eine vierte Meldung muss ich offen lassen. Am 20-09-2026 erschien CVE-2026-93964, Schweregrad mittel: Eine Prüf-Route für Zertifikate soll ohne Anmeldung erreichbar sein. Die Release Notes von 2.16.0 nennen sie nicht, und ich habe keinen Commit gefunden, der sich auf sie bezieht. Ob 2.16.0 sie schließt, kann ich dir deshalb nicht sagen. Sobald das Projekt sich dazu äußert, steht es hier.
Log-Viewer und Zugriffslisten pro Pfad
Zwei neue Funktionen, beide aus der Community. carlosalbertorg hat einen Log-Viewer in die Oberfläche gebaut: Was Nginx gerade an Zugriffen und Fehlern schreibt, siehst du jetzt im Browser statt per docker compose logs auf der Shell. Wenn ein Host „502 Bad Gateway“ liefert, ist das der Ort, an dem die Antwort steht. Ich hätte mir den Viewer für die Anleitung gewünscht; jetzt ist er da, und er nimmt Einsteigern den ersten Grund, das Terminal zu öffnen.
Die zweite Funktion von drakhaw heißt im Changelog „Per-path access lists“. Eine Zugriffsliste in NPM ist ein Türsteher: Benutzername und Passwort oder eine Liste erlaubter IP-Adressen, bevor der Dienst dahinter überhaupt antwortet. Bis jetzt galt ein Türsteher für den ganzen Host. Jetzt kann er an einem einzelnen Pfad stehen, also etwa vor /admin, während der Rest der Seite für alle offen bleibt. Das ist genau der Fall, den viele mit zwei Proxy Hosts oder eigener Nginx-Konfiguration nachgebaut haben. Nun ist es ein Formularfeld im Dialog des Proxy Hosts.
Kleiner, aber im Alltag spürbar: Nginx nutzt jetzt reuseport, mehrere Arbeitsprozesse verteilen sich damit gleichmäßiger auf eingehende Verbindungen. Wer Podman statt Docker fährt, bekommt Socket-Aktivierung. Und eine kaputte Nginx-Konfiguration, die NPM bisher stillschweigend verwarf, landet als Datei mit der Endung .conf.err im Datenordner, wo man sie lesen kann. Die deutsche Übersetzung der Oberfläche wurde ebenfalls nachgezogen.
Certbot 5.8.0: die Warnung im Release
Ganz oben in den Release Notes steht ein Satz in Fettschrift, und er gehört zu den ehrlichen: „Certbot has been updated. Exercise caution with this upgrade as your DNS plugins may not work as expected and require tweaks to dependencies.“ Certbot ist das Programm, mit dem NPM Zertifikate bei Let's Encrypt holt, und die DNS-Plugins sind die Anbindungen an deinen Domain-Anbieter, über die NPM kurz einen DNS-Eintrag setzt, um den Besitz der Domain zu beweisen. Certbot springt auf 5.8.0, und nicht jedes der vielen Plugins ist dafür schon getestet.
Betroffen bist du nur, wenn du im Reiter SSL den Weg „Let's Encrypt via DNS“ nutzt. Wer keine Zertifikate hat oder sie per HTTP holt, kann diesen Absatz überspringen. Für alle anderen mein Vorschlag: Update an einem Abend, an dem du Zeit hast, mit einer Kopie des Ordners letsencrypt daneben, und danach die Erneuerung eines Zertifikats von Hand anstoßen, statt auf den nächsten automatischen Lauf zu warten. Klappt sie nicht, ist dank der festen Versionsnummer der Rückweg auf 2.15.1 ein Handgriff. Nur ist das dann wieder die Version mit der Lücke, deshalb würde ich in dem Fall im Issue-Tracker nachsehen, ob dein Anbieter schon gemeldet ist, statt lange auf 2.15.1 zu bleiben.
Ein Stolperstein, der nichts mit Certbot zu tun hat: Am 25-09-2026 hat ein Nutzer Issue #5882 eröffnet, weil Dialoge und Menüs in 2.16.0 so durchsichtig geworden sind, dass der Hintergrund durchscheint und die Lesbarkeit leidet, auch ohne eigenes Theme. Das ist Kosmetik, keine Funktionsstörung, und eine Antwort vom Projekt gab es beim Schreiben dieses Beitrags noch nicht.
Update in drei Handgriffen
Wer NPM nach unserer Anleitung eingerichtet hat, steht auf der festen Nummer 2.15.1, und genau dafür war sie da. Die Anleitung selbst zeigt seit heute 2.16.0. Die Doku-Seite zum Upgrade verspricht, dass NPM seine Datenbank beim Start selbst anpasst, „so you don't have to follow any crazy instructions“.
In den Ordner wechseln und die Ordner sichern:
cd ~/nginx-proxy-manager
sudo cp -a data data.bak-2.15.1
sudo cp -a letsencrypt letsencrypt.bak-2.15.1Die Compose-Datei öffnen:
nano docker-compose.ymlIn der Zeile image: die 2.15.1 durch 2.16.0 ersetzen, mit Strg+O und Enter speichern, mit Strg+X schließen. Dann ziehen, neu starten und nachsehen:
docker compose pull && docker compose up -d
docker compose psIn der Spalte STATUS steht Up, und im Browser antwortet Port 81 nach kurzer Wartezeit mit der Anmeldeseite. Danach einmal durch die Liste der Proxy Hosts: Jeder steht auf Online, und der erste Name, den du eingerichtet hast, öffnet weiter den Dienst dahinter. Wer die Zwei-Faktor-Anmeldung schon hatte, geht jetzt den Weg von oben und richtet sie neu ein. Die Sicherungskopien können weg, sobald eine Woche lang nichts aufgefallen ist.
Bleibt die Frage, warum ich bei einem Projekt, das ein Sicherheitsupdate 109 Tage liegen lässt, weiter zum Update rate statt zum Wechsel. Weil die Alternativen denselben Preis haben: Traefik und Caddy sind Konfigurationsdateien, keine Formulare, und wer NPM wegen der Formulare gewählt hat, tauscht ein Problem gegen ein anderes. Und weil die drei Fixes von drei verschiedenen Leuten aus der Community kommen, die sich den Code angesehen haben, statt sich zu beschweren. Das ist der Teil von Open Source, der funktioniert. Der Release-Rhythmus ist der Teil, über den ich beim nächsten Mal wieder schreiben werde, falls er sich nicht ändert.
Hast du Port 81 bei dir jemals nach draußen gestellt, und wie hältst du es mit der festen Versionsnummer im Image: Segen oder Bremse? Schreib es in die Kommentare, mich interessiert auch, ob bei jemandem das DNS-Plugin nach dem Update gehakt hat.
Wer noch keinen Reverse Proxy betreibt und sich fragt, ob er einen braucht: Was ein Reverse Proxy ist, steht hier ohne Docker-Vorwissen erklärt. Und wer Port 81 mit einer Firewall dichtmachen wollte und sich wundert, dass Docker sie umgeht, findet den Grund und den Fix im Beitrag von Mittwoch.
Quellen
- Nginx Proxy Manager: Release v2.16.0 (24-09-2026, Certbot-Warnung, Log-Viewer, Per-path access lists, Sicherheitsfixes)
- GitHub Advisory GHSA-4pgp-q8h4-9wxm / CVE-2026-40519 (OS Command Injection, CVSS 7.7, Versionen 2.9.14 bis 2.15.1)
- Nginx Proxy Manager: Issue #5478, Meldung der Lücke (12-04-2026)
- Nginx Proxy Manager: Pull Request #5498, Changed order of escape to prevent RCE (gemergt 07-06-2026)
- Nginx Proxy Manager: Pull Request #5801, lokale QR-Code-Erzeugung statt api.qrserver.com
- Nginx Proxy Manager: Pull Request #5836, Tokens nach Passwortänderung ungültig (Issue #5833)
- GitHub Advisory GHSA-75h8-hx74-6qmf / CVE-2026-93964 (20-09-2026, Schweregrad mittel)
- Nginx Proxy Manager: Issue #5882, zu durchsichtige Dialoge in 2.16.0 (25-09-2026)
- Nginx Proxy Manager: Upgrading (docker compose pull, docker compose up -d)
- Docker Hub: jc21/nginx-proxy-manager, Tags latest, 2 und 2.16.0 (24-09-2026)
- GitHub API: Release-Daten v2.15.1 (03-06-2026) bis v2.16.0 (24-09-2026)