Traefik CVE-2026-114640: Der Klartext-Router reicht gefälschte Client-Zertifikate an das Backend durch
Wer hinter einem Ingress Client-Zertifikate verlangt, verlässt sich im Backend meist auf ein paar Header: Ssl-Client-Verify meldet, ob die Prüfung geklappt hat, und Ssl-Client-Subject-Dn sagt, wer sich ausgewiesen hat. Solche Header sind genau so viel wert wie die Instanz, die sie setzt. Im Ingress-NGINX-Provider von Traefik 3.7 setzte sie nur der TLS-Router einer Ingress, während der Klartext-Router derselben Ingress sie unverändert vom Client übernahm. Ist dort die HTTPS-Umleitung abgeschaltet, reicht ein selbst geschriebener Header, um sich als beliebige mTLS-Identität auszugeben. CVE-2026-114640 ist der greifbarste von mehreren Fehlern in derselben Übersetzungsschicht, die Traefik 3.7.14 schließt.
TL;DR — 90 Sekunden
- Was: Der Ingress-NGINX-Provider von Traefik hängt die Middleware für
auth-tls-pass-certificate-to-upstreamnur an den TLS-Router. Der HTTP-Router derselben Ingress reicht vom Client gesendeteSsl-Client-*-Header unverändert an das Backend weiter. - Schwere: CVSS 8.7 nach v3.1 (
AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:N) und 7.0 nach v4, eingestuft als CWE-290. Ein öffentlicher Exploit ist nicht bekannt, und die Lücke steht nicht im CISA-KEV-Katalog. - Wen es trifft: Traefik 3.7.0 bis 3.7.13 mit aktiviertem Ingress-NGINX-Provider, wenn eine Ingress Client-Zertifikate an das Backend weitergibt,
ssl-redirectdort auf"false"steht und das Backend den Headern vertraut. - Was zu tun ist: Auf Traefik 3.7.16 aktualisieren und vorher im Migrationsleitfaden prüfen, welche generierten Router neue Namen bekommen. 3.7.14 schließt zwar diese CVE, eine weitere mTLS-Lücke im selben Provider behebt aber erst 3.7.15.
- Was vorher geschützt hätte: eine HTTPS-Umleitung, die auf Ingresses mit Client-Prüfung per Admission-Regel nicht abgeschaltet werden kann, eine Middleware auf den Entrypoints, die Identitäts-Header löscht, bevor ein Router sie setzt, und ein Backend, das Header nicht als einzigen Identitätsnachweis nimmt.
Ein Ingress, zwei Router und nur ein Türsteher
Bei mutual TLS weist sich der Client mit einem Zertifikat aus. Der Server fordert es im Handshake an, und der Client beweist mit einer Signatur über den bisherigen Handshake, dass er den zugehörigen privaten Schlüssel besitzt. RFC 8446 nennt diese Nachricht CertificateVerify. Den Beweis sieht nur die Instanz, die TLS terminiert. Beim Backend hinter dem Ingress-Controller kommt bloß noch HTTP an, also muss das Ergebnis der Prüfung auf anderem Weg mitreisen. Ingress-NGINX nutzt dafür laut eigener Doku vier Header: ssl-client-verify mit dem Prüfergebnis, ssl-client-subject-dn und ssl-client-issuer-dn mit den Namen aus dem Zertifikat sowie ssl-client-cert mit dem vollständigen Zertifikat im PEM-Format, sobald die Annotation nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream auf "true" steht.
Kryptografisch ist an diesen Headern nichts gebunden. Ihr Wert beruht allein auf der Annahme, dass genau eine Instanz zwischen Client und Backend sie setzt und der Client sie nicht selbst mitschicken kann. Diese Annahme muss der Proxy auf jedem Weg zum Backend einlösen, nicht nur auf dem, den der Betreiber im Kopf hat.
Für Ingress-NGINX endete die Wartung laut Ankündigung des Kubernetes-Projekts im März 2026, danach sind weder Releases noch Sicherheitskorrekturen vorgesehen. Traefik bietet mit dem Ingress-NGINX-Provider einen Weg heraus an. Der Provider liest vorhandene Ingress-Ressourcen samt NGINX-Annotations und übersetzt sie in Traefik-Router, Middlewares und TLS-Optionen. Die Annotations für Client-Zertifikate versteht er laut Advisory seit Version 3.7.0. Zu einer Ingress mit TLS gehören dabei zwei Router: einer auf dem HTTPS-Entrypoint, an dem die Client-Prüfung hängt, und einer auf dem HTTP-Entrypoint. Der zweite leitet laut Advisory normalerweise nur auf HTTPS um, so wie Ingress-NGINX ab Werk mit einem 308 umleitet, sobald TLS für die Ingress aktiv ist.
Genau hier lag der Fehler. Die Middleware, die aus dem geprüften Zertifikat die Ssl-Client-*-Header baut, hing laut Advisory nur am TLS-Router. Der HTTP-Router bekam sie nicht und reichte deshalb alles weiter, was der Client an Headern mitbrachte. Solange er nur umleitet, ist das harmlos. Setzt jemand aber nginx.ingress.kubernetes.io/ssl-redirect: "false", leitet er die Anfrage an das Backend weiter. Ein Client ganz ohne Zertifikat kann dann Ssl-Client-Verify: SUCCESS und einen frei gewählten Subject-DN schicken. Die Client-Prüfung aus auth-tls-verify-client greift auf Port 80 gar nicht, denn sie ist an den TLS-Handshake gebunden, und den gibt es dort nicht.
Eine zweite Schwäche steckt in der Schreibweise der Header-Namen. HTTP erlaubt in Feldnamen auch Unterstriche, und Traefik reicht solche Header in der Standardeinstellung aliasHeadersStrategy: keep unverändert weiter. Für Anwendungen hinter CGI oder FastCGI ist das heikel, weil RFC 3875 Header-Namen in Großbuchstaben umwandelt und Bindestriche durch Unterstriche ersetzt. Ssl-Client-Verify und Ssl_Client_Verify fallen dadurch auf denselben Namen HTTP_SSL_CLIENT_VERIFY. nginx ignoriert Header mit Unterstrich in seiner Standardeinstellung, weil underscores_in_headers auf off und ignore_invalid_headers auf on steht. Traefik muss solche Aliase dagegen ausdrücklich entfernen, und genau das holt der Fix nach. Dasselbe Muster stand im Juni hinter dem Underscore-Header-Spoofing in FrankenPHP.
Was der Fix-Commit ändert
Den Fix liefert Pull Request #13912, der am 16. September in den Zweig v3.7 eingeflossen ist. Im Kern ändert er die Middleware in pkg/middlewares/ingressnginx/authtlspasscertificatetoupstream/auth_tls_pass_certificate_to_upstream.go. Laut Titel und Beschreibung hängt die Übersetzung in translator.go sie außerdem an den HTTP-Router jeder Ingress mit der Annotation. Neu ist eine feste Menge verwalteter Header, nämlich Ssl-Client-Cert, Ssl-Client-Verify, Ssl-Client-Subject-Dn und Ssl-Client-Issuer-Dn. Die neue Funktion deleteManagedHeaders geht bei jeder Anfrage über alle Header-Namen, normalisiert sie und löscht jeden Treffer. Bei der Normalisierung werden Buchstaben groß geschrieben, und jedes andere Zeichen außer Ziffern wird zum Bindestrich. Auf Header.Del verzichtet der Code mit Absicht, weil diese Funktion laut Kommentar genau die Alias-Schreibweisen verfehlen würde, gegen die der Fix schützen soll.
Erst nach dem Löschen entscheidet die Middleware, was sie setzt. Ohne TLS-Verbindung setzt sie gar nichts. Ein Kommentar im Code begründet das damit, dass nginx diese Header aus den Variablen $ssl_client_* baut, die außerhalb von TLS leer sind. Bei TLS ohne Client-Zertifikat steht Ssl-Client-Verify auf NONE, und nur mit geprüftem Zertifikat füllt die Middleware alle vier Header aus dem Zertifikat. Die neuen Tests decken beide Richtungen ab: Eine Klartext-Anfrage mit allen vier Headern endet ohne einen davon, während ein unbeteiligter Header wie X_Request_Id erhalten bleibt.
Die Beschreibung des Pull Requests fasst die Ursache in einem Satz zusammen: Diese Header gehören Traefik. Bis 3.7.13 war die Hoheit über die Identitäts-Header die Eigenschaft eines einzelnen Routers. Mit dem Fix wird sie zur Eigenschaft der Kante, die immer zuerst löscht und nur aus geprüftem Zustand neu setzt. Der Fehler lag also weniger in einer fehlenden Prüfung als in der Annahme, dass Anfragen nur über den Weg ankommen, für den die Prüfung gebaut war.
Vom Port 80 zur fremden Identität
Ab Werk ist niemand betroffen. Der Ingress-NGINX-Provider ist in Traefik nicht aktiv, solange du ihn nicht einschaltest, im Helm-Chart etwa mit providers.kubernetesIngressNginx.enabled: true. Damit ein Angriff gelingt, müssen außerdem mehrere Dinge zusammenkommen: eine Ingress mit auth-tls-secret und auth-tls-pass-certificate-to-upstream: "true", ein auf genau dieser Ingress abgeschaltetes ssl-redirect, ein erreichbarer HTTP-Entrypoint für den Host und ein Backend, das seine Autorisierung auf die Ssl-Client-*-Header stützt.
Heikel ist die Kombination vor allem bei einer Migration. Laut dem Code-Kommentar im Fix trägt eine Klartext-Anfrage hinter nginx keinen dieser Header, weil nginx sie nur aus TLS-Variablen befüllt. Wer Ingress-Ressourcen mitsamt ihren Annotations aus einer Ingress-NGINX-Installation übernimmt, verlässt sich darauf, dass die Übersetzung diese Eigenschaft mitnimmt. In Traefik 3.7.0 bis 3.7.13 tat sie das nicht.
Der Angriff selbst besteht aus einer einzigen HTTP-Anfrage. Der Angreifer schickt sie im Klartext an den Host, setzt Ssl-Client-Verify auf SUCCESS und trägt als Subject-DN die Identität ein, die er annehmen will. Traefik reicht die Anfrage über den HTTP-Router an das Backend, und dort sieht sie aus wie eine erfolgreiche mTLS-Anmeldung. Wie groß der Schaden ist, hängt davon ab, was diese Identität im Backend darf. Die CVSS-Bewertung bildet das ab, denn sie sieht keine Wirkung auf Traefik selbst, aber eine hohe Wirkung auf Vertraulichkeit und Integrität des nachgelagerten Systems.
Die CVE betrifft laut Advisory allein den Ingress-NGINX-Provider, und zwar nur in der Linie 3.7, weil ältere Versionen die Annotation gar nicht übersetzen. Wer Traefik ohne diesen Provider betreibt, ist davon nicht betroffen. Das Update lohnt sich trotzdem, denn CVE-2026-114640 kam nicht allein.
Dasselbe Release schließt weitere Fehler, bei denen eine Anfrage an einer Prüfung vorbeikommt, die der Betreiber für gesetzt hielt. Bei CVE-2026-114638 erzeugten zwei Secrets, deren Namen sich nur durch Punkt und Bindestrich unterscheiden, denselben Namen für die TLS-Option, sodass ein Host die Client-CA eines anderen Hosts akzeptierte. Bei GHSA-qvj7-gq9c-hp7q bekam eine Ingress mit ssl-passthrough ab 3.7.13 einen zusätzlichen HTTP-Router, an dem Basic Auth, auth-url und whitelist-source-range nie ankamen. GHSA-fh26-gfpp-7xxx betrifft alle Provider: Mit Go 1.27 gebaute Traefik-Binaries übersprangen die SNI-Prüfung für HTTP/2-Anfragen mit :scheme http über eine TLS-Verbindung, wodurch ein Router mit Zertifikatspflicht ohne Zertifikat erreichbar wurde. Die offiziellen Images baut Traefik laut Advisory mit Go 1.26, Rebuilds von Dritten können aber betroffen sein. Schon 3.7.11 hatte mit GHSA-j994-9gqj-9hwq einen Fall behoben, in dem ein Konflikt zwischen TLS-Optionen auf die Standardoptionen ohne Client-Prüfung zurückfiel. Und mit GHSA-p8wx-ph99-xgcr folgte am 15. Oktober in 3.7.15 ein weiterer: Teilen sich mehrere Ingresses einen Host und tragen nur einige davon auth-tls-secret, fiel der Host laut Advisory ebenfalls auf Standardoptionen ohne Client-Zertifikat zurück, sofern core.strictTLSOptions nicht eingeschaltet war. Betroffen waren alle 3.7-Versionen bis einschließlich 3.7.14.
| CVE / Advisory | Betroffen | Fix | Voraussetzung | CVSS |
|---|---|---|---|---|
| CVE-2026-114640 (GHSA-mwrr-6hp4-pxr6) | 3.7.0 bis 3.7.13 | 3.7.14 | Ingress-NGINX-Provider, auth-tls-pass-certificate-to-upstream, ssl-redirect: "false", Backend vertraut den Headern | 8.7 v3.1 / 7.0 v4 (hoch) |
| CVE-2026-114638 (GHSA-rv2h-qh7j-xrjw) | 3.7.0 bis 3.7.13 | 3.7.14 | Zwei auth-tls-secret-Namen, die sich nur durch Punkt und Bindestrich unterscheiden | 7.0 v4 (hoch) |
| GHSA-qvj7-gq9c-hp7q (ohne CVE) | 3.7.13 | 3.7.14 | ssl-passthrough plus Zugriffs-Annotations, HTTP-Entrypoint erreichbar | 7.0 v4 (hoch) |
| GHSA-fh26-gfpp-7xxx (ohne CVE) | bis 2.11.57, 3.0.0 bis 3.7.13, nur mit Go 1.27 gebaut | 2.11.58 / 3.7.14 | TLS-Option mit Client-Prüfung, HTTP/2 mit :scheme http | 7.0 v4 (hoch) |
| GHSA-p8wx-ph99-xgcr (ohne CVE) | 3.7.0 bis 3.7.14 | 3.7.15 | Mehrere Ingresses auf einem Host, nur einige mit auth-tls-secret | 7.0 v4 (hoch) |
| GHSA-j994-9gqj-9hwq, Vorgänger | 3.7.0 bis 3.7.10 | 3.7.11 | Ein Host auf mehreren Ingresses mit Client-Prüfung | 8.2 v4 (hoch) |
Die Advisories erschienen am 7. Oktober, die CVE-Nummer vergab VulnCheck erst am 22. Oktober. Beide CVSS-Werte stehen im CVE-Eintrag und beschreiben dieselbe Lücke nach zwei Versionen des Standards: 8.7 nach v3.1, 7.0 nach v4. Einen öffentlichen Exploit nennt bis zum 27. Oktober keine der geprüften Quellen, Angriffe sind nicht bekannt, und im CISA-KEV-Katalog steht die Lücke nicht. EPSS schätzt die Wahrscheinlichkeit einer Ausnutzung in den nächsten 30 Tagen auf 0,20 Prozent. Das Advisory beschreibt die Anfrage allerdings so genau, dass ein Nachbau keine besonderen Kenntnisse verlangt.
Traefik 3.7.14, 3.7.16 und die neuen Router-Namen
Der Fix für CVE-2026-114640 steckt in Traefik 3.7.14, das am 6. Oktober erschienen ist. Dabei solltest du nicht stehen bleiben. Am 15. Oktober folgte 3.7.15 mit drei weiteren Advisories, darunter die oben beschriebene mTLS-Lücke GHSA-p8wx-ph99-xgcr im selben Provider. Seit dem 21. Oktober ist 3.7.16 verfügbar, das mit GHSA-hrpp-p4fc-wwf8 eine Lücke in ForwardAuth schließt, die im Ingress-NGINX-Provider auch die Annotation auth-url betrifft. Ich würde deshalb direkt auf 3.7.16 gehen. Die Zweige 3.0 bis 3.6 bekommen laut den Advisories keine Patches mehr, wer dort steht, muss auf 3.7 wechseln. Für Traefik 2.11 spielt CVE-2026-114640 keine Rolle, die Fixes für die übrigen Lücken des Releases stecken dort in 2.11.58 und neuer.
Vor dem Update solltest du die Änderungen kennen, die es mitbringt. Laut Migrationsleitfaden ersetzt der Ingress-NGINX-Provider Punkte in Ingress- und Secret-Namen nicht mehr durch Bindestriche. Damit ändern sich die Namen generierter Router, aus einer Ingress my.ingress wird etwa der Router default-my.ingress-rule-0-path-0. Router und Middlewares für Ingresses mit ssl-passthrough folgen jetzt dem Muster <namespace>-<ingress>-rule-<rule index>-path-<path index>. Dashboards, Alarme und Abfragen gegen die Traefik-API, die noch mit den alten Namen arbeiten, laufen danach ins Leere. Auch die Namen von TLSRoute-Routern ändern sich, und bei der Gateway API bedient von zwei identischen Routen auf demselben Listener nur noch eine den Verkehr.
Zwei Stolperfallen betreffen die Anwendungen hinter Traefik. Ein Backend, das auf Klartext-Anfragen bisher Ssl-Client-*-Header gesehen hat, bekommt dort keine mehr, und Varianten dieser Header mit Unterstrich kommen auch über TLS nicht mehr an. Wer aus älteren Versionen kommt, nimmt außerdem die Änderung aus 3.7.13 mit, nach der Traefik die Header Upgrade: h2c und HTTP2-Settings nicht mehr an Backends weiterreicht. Backends, die unverschlüsseltes HTTP/2 brauchen, erreichst du dann nur noch über das Schema h2c:// in der Server-URL.
Einen offiziellen Workaround nennt das Advisory nicht. Weil die Anfrage laut Advisory nur bei abgeschaltetem ssl-redirect das Backend erreicht, schließt du den Weg von CVE-2026-114640 bis zum Update, indem du die Umleitung auf allen Ingresses mit Client-Prüfung wieder einschaltest. Gegen die verwechselten Client-CAs und den Passthrough-Router hilft das allerdings nicht.
Härtung über den Patch hinaus
Zuerst eine Einordnung. Traefik führt bei diesem Angriff keinen fremden Code aus und gerät in keinen undefinierten Zustand. Er leitet eine Anfrage weiter, wie er es soll, nur auf einem Weg, auf dem die Identitätsprüfung fehlt. Wirksam ist deshalb, was Klartext-Wege zu geschützten Backends verhindert, Identitäts-Header an der Kante unter Kontrolle hält, bei Konflikten in der TLS-Konfiguration geschlossen statt offen versagt und das Backend weniger abhängig von Headern macht. Was nur den Traefik-Container härtet, verfehlt diesen Mechanismus.
Klartext-Weg per Admission-Regel verbieten
Laut Advisory erreicht die gefälschte Anfrage das Backend nur, wenn ssl-redirect auf der Ingress abgeschaltet ist. Diese Kombination lässt sich prüfen, bevor die Ressource überhaupt im Cluster landet. Eine ValidatingAdmissionPolicy, seit Kubernetes 1.30 allgemein verfügbar, kann Ingresses ablehnen, die auth-tls-secret oder auth-tls-pass-certificate-to-upstream setzen und zugleich ssl-redirect auf "false" stellen. Die Bedingung lässt sich in CEL direkt über metadata.annotations formulieren. Eine zweite Regel kann festlegen, welcher Namespace welchen Host bedienen darf. Sie zielt auf die Vorgänger-Lücke GHSA-j994-9gqj-9hwq, bei der laut Advisory ein Mandant mit einer eigenen Ingress für einen vorhandenen Host den Konflikt auslösen konnte. Kyverno oder Gatekeeper leisten dasselbe, falls du eines davon schon betreibst. Weitere Muster für Admission-Policies und Mandantentrennung findest du in der Serie TYPO3 auf Kubernetes unter IT-Grundschutz.
Der Betriebsaufwand ist gering, solange niemand diese Kombination wirklich braucht, und genau das prüfst du vor dem Scharfschalten im Bestand. Die Grenze der Regel liegt darin, dass sie allein den Weg dieser einen CVE schließt. Gegen verwechselte Client-CAs oder den Passthrough-Router hilft sie nicht.
Identitäts-Header an den Entrypoints löschen
Der Fix macht Traefik zum Eigentümer der Ssl-Client-*-Header. Dieses Prinzip kannst du auch selbst umsetzen. Die Headers-Middleware entfernt einen Request-Header, wenn du ihn in customRequestHeaders auf einen leeren String setzt. Eine solche Middleware für Ssl-Client-Verify, Ssl-Client-Subject-Dn, Ssl-Client-Issuer-Dn und Ssl-Client-Cert hängst du über entryPoints.<name>.http.middlewares an die Entrypoints. Laut Doku stellt Traefik diese Middlewares der Liste jedes Routers auf dem Entrypoint voran und führt sie in der angegebenen Reihenfolge aus. Auf dem HTTP-Entrypoint verschwinden die gefälschten Werte damit, bevor irgendein Router sie weiterreichen kann. Auf dem HTTPS-Entrypoint läuft das Löschen vor der Middleware des Providers, die anschließend die geprüften Werte setzt.
Das Löschen über den Namen trifft allerdings nur die kanonische Schreibweise. Gegen Varianten mit Unterstrich bietet Traefik 3.7 die Entrypoint-Option http.aliasHeadersStrategy. Mit delete entfernt Traefik jeden Request-Header, dessen Name andere Zeichen als Buchstaben, Ziffern und Bindestriche enthält, mit reject beantwortet er solche Anfragen mit 400. Standard ist keep. Die Doku weist zu Recht darauf hin, dass beide Modi auch legitime Header wie X_Request_Id treffen. Sieh deshalb vor dem Umschalten in den Access-Logs nach, ob deine Clients solche Namen senden. Für PHP-Anwendungen hinter Traefik halte ich delete für die richtige Grundeinstellung, weil RFC 3875 Bindestrich und Unterstrich ohnehin zusammenfallen lässt.
Backends, die Headern nicht allein glauben
Ein Backend, das Identität aus Headern liest, sollte wenigstens wissen, dass die Anfrage von Traefik kommt. Dafür baust du zwischen Traefik und Backend selbst mTLS auf: Traefik meldet sich über ein Client-Zertifikat im ServersTransport an, und das Backend nimmt nur Verbindungen mit diesem Zertifikat an. Wie Traefik dafür eine eigene Identität bekommt, habe ich in Traefik weist sich selbst aus beschrieben. Zusätzlich begrenzt eine NetworkPolicy den Zugriff auf das Backend auf die Traefik-Pods. Beides schützt vor gefälschten Headern, die an Traefik vorbei ans Backend gelangen. Gegen CVE-2026-114640 selbst hilft es nicht, denn hier kam die Fälschung durch Traefik.
TLS-Optionen geschlossen versagen lassen
Gleich drei Lücken aus dieser Reihe, GHSA-j994-9gqj-9hwq, GHSA-p8wx-ph99-xgcr und CVE-2026-114638, drehen sich um TLS-Optionen, und die ersten beiden enden gleich: Zwei Router ordnen demselben Host unterschiedliche TLS-Optionen zu, Traefik verwirft beide Zuordnungen und fällt auf die Option default zurück, die keine Client-Zertifikate verlangt. Die Traefik-Doku hält selbst fest, dass ein Router mit clientAuth seine Prüfung dann nicht mehr durchsetzt. Die Install-Option core.strictTLSOptions: true, als Flag --core.strictTLSOptions=true, schaltet diesen Rückfall ab. Laut Doku werden die beteiligten Router dann als fehlerhaft markiert und gar nicht erst gebaut. Der Host bleibt bis zur Klärung unerreichbar, und genau das willst du bei einem mTLS-geschützten Dienst. Das Advisory zu GHSA-p8wx-ph99-xgcr nennt die Option ausdrücklich als Bedingung: Mit eingeschaltetem core.strictTLSOptions fiel der Host dort nicht auf die Standardoptionen zurück.
Der Preis ist eine neue Art von Ausfall. Legt ein Team für einen vorhandenen Host eine zweite Ingress mit abweichender TLS-Option an, fällt der Host aus, statt still unsicher zu werden. Zur Option gehören deshalb ein Monitoring auf Router-Fehler und eine klare Zuständigkeit für Hosts. Außerdem sollte die TLSOption default nicht schwächer sein als nötig, denn sie ist laut Doku der Rückfall für jeden Konflikt.
Die Übersetzungsschicht als Übergangslösung
Der Ingress-NGINX-Provider ist eine Kompatibilitätsschicht. Er muss das Verhalten eines anderen Proxys nachbilden, und jede Stelle, an der das nicht genau gelingt, kann zum Sicherheitsfehler werden. Zwischen 3.7.11 und 3.7.16 betreffen gleich mehrere Advisories genau diese Schicht. Ich sehe den Provider deshalb als Werkzeug für die Migration und nicht als Dauerlösung. mTLS-geschützte Dienste würde ich mittelfristig auf native Traefik-Ressourcen oder die Gateway API umstellen, wo du TLS-Optionen und Router selbst festlegst, statt sie aus fremden Annotations ableiten zu lassen.
Was hier nicht hilft
seccomp, entzogene Capabilities, runAsNonRoot, allowPrivilegeEscalation: false und readOnlyRootFilesystem bleiben für Traefik richtig, zielen aber auf Code, der im Container Schaden anrichtet. Solchen Code gibt es hier nicht. Dasselbe gilt für den Pod Security Standard „restricted“, für User Namespaces und für ein minimales Base-Image. Auch eine Egress-Sperre für Traefik bewirkt nichts, weil die Anfrage den erlaubten Weg zum Backend nimmt.
Ebenso wenig hilft die naheliegende Idee, im Backend das Zertifikat aus Ssl-Client-Cert gegen die eigene CA zu prüfen. Ein Zertifikat ist öffentlich. Wer eines kennt, kann es in einen Header schreiben, ohne den privaten Schlüssel zu besitzen. Den Besitz beweist nur die Signatur im TLS-Handshake, und die sieht nur, wer TLS terminiert. Ein CVE-Gate in der Pipeline schließlich hätte die Lücke zwei Wochen lang übersehen, denn zwischen den Advisories am 7. Oktober und der CVE-Nummer am 22. Oktober lagen 15 Tage. Ein automatisches Image-Update hätte 3.7.14 dagegen kurz nach dem Release als Merge Request vorgeschlagen, ganz gleich, ob es schon eine CVE-Nummer gab.
Erkennung und Prüfung
Ob du betroffen bist, klärst du in drei Schritten. Zuerst die Version: Jedes Traefik-Image von 3.7.0 bis 3.7.13 enthält die Lücke. Dann die Konfiguration: Ob der Ingress-NGINX-Provider läuft, erkennst du an --providers.kubernetesingressnginx in den Argumenten oder an providers.kubernetesIngressNginx.enabled in den Helm-Values. Zuletzt die Ressourcen: Suche alle Ingresses mit nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: "true" und prüfe, ob bei einer davon ssl-redirect auf "false" steht. Bei der Gelegenheit lohnt der Blick auf auth-tls-secret-Werte, die sich nur durch Punkt und Bindestrich unterscheiden, auf Hosts, die mehrere Ingresses teilen, und unter 3.7.13 auf Ingresses mit ssl-passthrough.
Schwerer zu beantworten ist die Frage, ob jemand die Lücke ausgenutzt hat, denn weder Hersteller noch Advisory nennen Indikatoren. Ich würde in den Traefik-Access-Logs nach Anfragen an mTLS-geschützte Hosts suchen, deren RequestSchemehttp lautet und die nicht mit einer Umleitung, sondern mit einem Status aus dem 2xx-Bereich endeten. Die dokumentierten Felder RequestHost, RequestScheme, RouterName und DownstreamStatus reichen dafür aus. Request-Header schreibt Traefik ab Werk nicht ins Access-Log, weil accesslog.fields.headers.defaultMode auf drop steht. Die gefälschten Werte selbst siehst du dort also nur, wenn du das Header-Logging ausdrücklich eingeschaltet hast. Dieses Suchmuster ist meine eigene Ableitung.
Bei einem Verdacht schaltest du zuerst ssl-redirect auf den betroffenen Ingresses wieder ein. Danach prüfst du im Backend, welche Aktionen unter den betroffenen Identitäten gelaufen sind, und entwertest Sitzungen und Tokens, die das Backend auf Grundlage dieser Identitäten ausgestellt hat. Das Update auf 3.7.16 folgt im selben Zug.
Betreiberempfehlung
Akut handeln solltest du, wenn Traefik 3.7.0 bis 3.7.13 mit dem Ingress-NGINX-Provider Dienste mit Client-Zertifikaten ausliefert und irgendwo ssl-redirect abgeschaltet ist. Schalte die Umleitung sofort wieder ein, aktualisiere auf 3.7.16 und prüfe vorher, welche Dashboards und Alarme an generierten Router-Namen hängen. Dasselbe gilt, wenn du Traefik aus einem Rebuild mit Go 1.27 betreibst und TLS-Optionen mit Client-Prüfung nutzt.
Beobachten genügt, wenn du Traefik ohne den Ingress-NGINX-Provider und mit dem offiziellen Image betreibst. Ins nächste Wartungsfenster gehört das Update trotzdem, denn 3.7.14 bis 3.7.16 schließen weitere Lücken, etwa bei ForwardAuth und beim Umgang mit NTLM- und Kerberos-Verbindungen, die nichts mit dem Provider zu tun haben.
Wie bei jeder Lücke gilt auch hier: Patches und Updates gehören automatisiert. Wenn Renovate oder Dependabot neue Versionen des Traefik-Helm-Charts und des Images selbstständig als Merge Request vorschlagen und die Pipeline sie gegen eine Staging-Umgebung testet, ist ein Security-Release wie 3.7.14 eine Sache von Stunden und nicht von Wochen. Eine Karenzzeit von ein paar Tagen für Routine-Updates schützt vor kompromittierten Releases, Sicherheitsupdates nimmst du davon aus. Gerade die umbenannten Router zeigen, was dieser Ablauf wert ist, denn ein gebrochener Alarm oder eine nicht mehr auflösbare Middleware-Referenz fällt dann in Staging auf und nicht im Betrieb. Wie schnell sich bei Traefik Rückstand aufbaut, zeigt der Kalender: Zwischen dem 26. August und dem 21. Oktober erschienen mit 3.7.12 bis 3.7.16 fünf Releases, die jeweils Security-Advisories schließen. Wer von Hand aktualisiert und dazwischen zwei Wochen Urlaub hat, spielt am Ende mehrere davon auf einmal ein, samt aller Umbenennungen.
Häufige Fragen zu CVE-2026-114640
Bin ich betroffen, wenn ich den Ingress-NGINX-Provider nicht nutze?+
Von dieser CVE nicht. Sie steckt laut Advisory allein im Ingress-NGINX-Provider ab Version 3.7.0. Das Update lohnt sich trotzdem, weil dasselbe Release weitere Lücken schließt, die unabhängig vom Provider sind.
Reicht es, ssl-redirect wieder einzuschalten?+
Warum prüft das Backend nicht einfach das Zertifikat aus Ssl-Client-Cert?+
Weil ein Zertifikat öffentlich ist. Wer eines kennt, kann es in einen Header schreiben, ohne den privaten Schlüssel zu besitzen. Den Besitz beweist nur die Signatur im TLS-Handshake, und die sieht allein die Instanz, die TLS terminiert.
Was bringt die Option aliasHeadersStrategy?+
Sie regelt, was mit Headern passiert, deren Name Unterstriche oder andere Sonderzeichen enthält. Mit delete entfernt Traefik sie, mit reject lehnt er die Anfrage ab. Das schließt Aliase wie Ssl_Client_Verify, die nach RFC 3875 auf denselben CGI-Namen fallen wie das Original. Prüfe vorher, ob deine Clients legitime Header mit Unterstrich senden.
Fazit
CVE-2026-114640 ist kein exotischer Speicherfehler, sondern ein Fehler in der Frage, wem ein Header gehört. Der Proxy hat die Identität richtig geprüft, aber nur auf einem von zwei Wegen zum selben Backend, und auf dem anderen hat er die Behauptung des Clients durchgereicht. Die Lehre reicht weit über Traefik hinaus. Jeder Header, den ein Backend als Identität liest, braucht an der Kante einen Eigentümer, der ihn auf jedem Weg zuerst löscht und nur aus geprüftem Zustand neu setzt. Und jede Konfiguration, die bei einem Konflikt auf eine schwächere Voreinstellung zurückfällt, sollte stattdessen ausfallen. Wer gerade von Ingress-NGINX migriert, sollte seine mTLS-geschützten Dienste deshalb einmal gezielt von Port 80 aus ansehen.
Quellen
- GitHub Advisory GHSA-mwrr-6hp4-pxr6 (CVE-2026-114640)
- CVE-Eintrag CVE-2026-114640 (VulnCheck, CVSS 3.1 und 4.0)
- Traefik Pull Request #13912: Ssl-Client-* headers on the Ingress-NGINX HTTP router
- GitHub: Traefik Release v3.7.14
- GitHub: Traefik Release v3.7.15
- Traefik Community: Security Update 2.11.60 und 3.7.16
- Traefik Docs: Migration v3.7.14
- GitHub Advisory GHSA-rv2h-qh7j-xrjw (CVE-2026-114638)
- GitHub Advisory GHSA-qvj7-gq9c-hp7q (ssl-passthrough)
- GitHub Advisory GHSA-fh26-gfpp-7xxx (snicheck)
- GitHub Advisory GHSA-p8wx-ph99-xgcr (mTLS bei geteiltem Host)
- GitHub Advisory GHSA-j994-9gqj-9hwq (TLS-Optionskonflikt)
- FIRST: EPSS für CVE-2026-114640
- Traefik Docs: EntryPoints (Middlewares, aliasHeadersStrategy)
- Traefik Docs: TLS Options und strictTLSOptions
- Traefik Docs: Headers Middleware
- Traefik Docs: Logs und Access-Logs
- Traefik Docs: Kubernetes Ingress NGINX Provider
- Ingress-NGINX Docs: Annotations (Client Certificate Authentication, ssl-redirect)
- Kubernetes Blog: Ingress NGINX Retirement
- RFC 8446, Abschnitt 4.4.3: Certificate Verify
- RFC 3875, Abschnitt 4.1.18: Protocol-Specific Meta-Variables
- nginx Docs: underscores_in_headers und ignore_invalid_headers
Ich prüfe deine Traefik-Kante auf ungeschützte Klartext-Wege und fremde Identitäts-Header, stelle mTLS auf geschlossenes Versagen um und automatisiere deine Traefik-Updates.
Traefik- und Ingress-Audits nach der Migration von Ingress-NGINX, Header-Hygiene und mTLS bis ins Backend, Admission-Regeln für Ingress-Annotations, Update-Automatisierung mit Renovate und getesteten Pipelines.
Plattform-Betrieb statt Beratung auf Papier: Ich prüfe, patche und härte deine Infrastruktur laufend.
