Zum Inhalt springen

Eigene Forschung

CVE-2026-104776: Dateilesen über kubectl_patch in mcp-server-kubernetes erklärt

Von Lucas Weber, CyberSec42 · Stand 28.10.2026

Schematische Darstellung eines MCP-Servers zwischen KI-Client und Zielsystem

CVE-2026-104776 ist eine Schwachstelle im Open-Source-Projekt mcp-server-kubernetes: Das Werkzeug kubectl_patch nahm über den Parameter patchFile einen Dateipfad an und ließ kubectl diese Datei auf dem Server lesen, auch wenn der Server über einen Netzwerk-Transport betrieben wurde. Die vier Geschwister-Werkzeuge mit vergleichbarem Pfad-Parameter lehnten genau das bereits ab, kubectl_patch fehlte diese Prüfung. Die GitHub-Advisory bewertet die Lücke mit CVSS 7.1 (hoch), betroffen sind alle Versionen bis einschließlich 4.1.0, behoben ist sie in 4.1.1, gemeldet von CyberSec42.

Kurz gefasst.

Hintergrund

Was der Server macht und welche Betriebsarten er kennt.

Zum Abschnitt

Die Schwachstelle

Mechanik in einfachen Worten und technisch.

Zum Abschnitt

Wer betroffen war

Versionen und Betriebsarten.

Zum Abschnitt

Behebung

Was der Fix ändert und was Betreiber tun sollten.

Zum Abschnitt

Zeitleiste

Nur öffentlich belegte Daten.

Zum Abschnitt

Das Muster dahinter

Wenn einem Werkzeug die Prüfung seiner Geschwister fehlt.

Zum Abschnitt

Die Fakten auf einen Blick

MerkmalAngabe
KennungCVE-2026-104776 (zugeteilt), GHSA-6963-p4fp-2wxw
Produktmcp-server-kubernetes (npm, Repository Flux159/mcp-server-kubernetes)
KlasseServerseitiges Lesen beliebiger Dateien; CWE-73 „External Control of File Name or Path“
SchwereCVSS 3.1: 7.1, hoch (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N)
Betroffenalle Versionen bis einschließlich 4.1.0, nur bei Betrieb über SSE oder Streamable HTTP
Behoben4.1.1, veröffentlicht am 27.07.2026
VeröffentlichtGitHub-Advisory am 02.10.2026; der CVE-Eintrag bei MITRE war am 28.10.2026 noch nicht veröffentlicht
CreditGemeldet von CyberSec42 (GitHub: lwebmedia)

Hintergrund: Was mcp-server-kubernetes ist

Das Model Context Protocol (MCP) ist ein offener Standard, über den KI-Assistenten Werkzeuge ansprechen. mcp-server-kubernetes ist ein quelloffener MCP-Server unter MIT-Lizenz, der laut Repository Befehle zur Verwaltung von Kubernetes bereitstellt. Er übersetzt Werkzeugaufrufe eines KI-Clients in Aufrufe von kubectl und helm, etwa kubectl_get, kubectl_apply oder kubectl_patch. Dabei handelt der Server mit den Kubernetes-Zugangsdaten, die auf seinem Host hinterlegt sind.

Für diesen Fall entscheidend ist die Betriebsart, im MCP-Jargon der Transport. Standard ist stdio: Der KI-Client startet den Server als lokalen Prozess, Aufrufer und Betreiber sind dieselbe Person auf demselben Rechner. Optional lässt sich der Server über die Umgebungsvariablen ENABLE_UNSAFE_SSE_TRANSPORT oder ENABLE_UNSAFE_STREAMABLE_HTTP_TRANSPORT als Netzwerkdienst starten. Die erweiterte Dokumentation des Projekts beschreibt beide Wege samt Docker-Beispiel und empfiehlt für den Produktivbetrieb zusätzlich eine Header-Authentifizierung über MCP_AUTH_TOKEN.

Im Netzwerkbetrieb gilt ein Grundsatz, den das Projekt selbst im Quellcode festhält: Ein Dateipfad, den ein Aufrufer übergibt, wird auf dem Server-Host aufgelöst, nicht beim Aufrufer. Deshalb hatten die Maintainer im Juli 2026 in zwei Pull Requests (#332 und #346) Pfad-Parameter für Netzwerk-Transporte gesperrt, und zwar bei kubectl_create, kubectl_apply, kubectl_delete sowie bei Installation und Upgrade von Helm-Charts. Grundsätzliches zur Absicherung solcher Server steht in unserem Leitfaden zu MCP-Servern; hier geht es um den konkreten Fall.

Wie wir geprüft haben

Der Befund stammt aus einer reinen Quellcode-Prüfung des öffentlichen Repositorys. Laut Advisory wurde dabei weder eine fremde Installation von mcp-server-kubernetes noch ein Kubernetes-Cluster, eine Kubeconfig oder ein anderes fremdes System angesprochen, gescannt oder ausgenutzt. Das abweichende Verhalten haben wir ausschließlich auf dem eigenen Rechner gegen den kompilierten Code nachgestellt, ohne Netzwerkanfrage und ohne Cluster. Die Meldung lief vertraulich über die private Schwachstellenmeldung des Repositorys auf GitHub.

Die Schwachstelle

In einfachen Worten

Stellen Sie sich ein Büro vor, in dem Besucher Formulare einreichen. Für vier Formulartypen gilt die Regel: Besucher von außen dürfen nicht auf „das Dokument im Schrank, Fach 3“ verweisen, sie müssen ihre Unterlagen selbst mitbringen. Beim fünften Formulartyp fehlte diese Regel. Ein Besucher konnte dort auf ein Fach im Schrank verweisen, und der Sachbearbeiter holte das Dokument heraus und arbeitete damit. Passte es nicht ins Formular, las er in seiner Rückmeldung Teile davon vor.

So verhielt sich kubectl_patch bis Version 4.1.0. Der Schrank ist das Dateisystem des Servers, das Fach ist der Parameter patchFile.

Technisch

Das Werkzeug kubectl_patch akzeptiert die Änderung entweder direkt als Daten (patchData) oder als Pfad zu einer Datei (patchFile). Den Pfad reichte es als --patch-file an kubectl weiter, das auf dem Server-Host mit dessen Rechten läuft. Die Geschwister-Werkzeuge prüfen vor genau diesem Schritt mit der Funktion isRemoteTransport(), ob der Server über das Netzwerk betrieben wird, und lehnen den Pfad dann ab. In kubectl-patch.ts fehlte dieser Aufruf. Eine zweite, allgemeine Schutzschicht des Projekts prüft zwar alle Argumente für kubectl, laut Advisory aber nur die Namen bestimmter Optionen, nicht den Wert dahinter. Für den Pfad bot sie deshalb keinen Schutz.

Wie Inhalte zurückfließen konnten, beschreibt die Advisory in zwei Varianten. Ist die Datei kein gültiges JSON oder YAML, scheitert kubectl beim Einlesen, und die Fehlermeldung samt Kontext aus der Datei wurde unverändert in der Antwort an den Aufrufer zurückgegeben. Ist die Datei gültig, was bei vielen Konfigurations- und Zugangsdateien naheliegt, wird ihr Inhalt als Patch auf eine Kubernetes-Ressource angewendet. Diese Ressource kann der Aufrufer anschließend über kubectl_get vollständig lesen.

Zur Einordnung des Vektors: PR:L bedeutet, dass ein Aufrufer niedrige Berechtigungen braucht, hier einen gültigen Wert für den Header X-MCP-AUTH, wenn der Betreiber MCP_AUTH_TOKEN gesetzt hat. C:H steht für den Verlust der Vertraulichkeit, I:L für die begrenzte Integritätsauswirkung des ungewollten Patches. Wir haben den Basiswert von 7.1 anhand der Formel der CVSS-Spezifikation nachgerechnet. Die Advisory weist selbst darauf hin, dass der Wert ohne gesetzten Token höher läge, rund 8.2, und dass ein Betreiber mit offenem Netzwerk-Transport ohne Token ohnehin allen erreichbaren Aufrufern weitreichende Cluster-Werkzeuge zugänglich macht. Beide Werte liegen im Band „hoch“, gemeldet wurde der niedrigere.

Schematischer Ablauf

Aufrufer übergibt Server-Pfad MCP-Server SSE / HTTP Geschwister lehnen den Pfad ab kubectl_patch liest die Datei Pfad-Prüfung vorhanden bis 4.1.0 ohne Prüfung
Bei Netzwerk-Transport lehnten die Geschwister-Werkzeuge Server-Pfade bereits ab. Bei kubectl_patch fehlte die Prüfung bis 4.1.0, ab 4.1.1 gilt dieselbe Regel.
  1. Der Betreiber startet mcp-server-kubernetes mit SSE oder Streamable HTTP. Auf dem Host liegen Kubernetes-Zugangsdaten.
  2. Ein Aufrufer, der den Endpunkt erreicht und gegebenenfalls den Auth-Header kennt, ruft kubectl_patch mit einem Pfad auf dem Server-Host als patchFile auf.
  3. Der Server prüft den Transport nicht und übergibt den Pfad an kubectl, das die Datei mit den Rechten des Servers öffnet.
  4. Ist die Datei kein gültiger Patch, enthält die zurückgegebene Fehlermeldung Kontext aus der Datei. Ist sie gültig, landet ihr Inhalt in einer Ressource, die über kubectl_get lesbar ist.

Wir veröffentlichen bewusst keinen Exploit-Code und keine Beispielanfrage. Die Beschreibung reicht, um die eigene Installation einzuordnen und den Fix nachzuvollziehen.

Wer betroffen war

Die Advisory nennt das npm-Paket mcp-server-kubernetes in allen Versionen bis einschließlich 4.1.0. Im Quellcode von 4.1.0 fehlt der Aufruf von isRemoteTransport() in kubectl-patch.ts, ab 4.1.1 ist er vorhanden. Ob ein Server über das Netzwerk betrieben wird, entscheidet die Funktion allein anhand der beiden Umgebungsvariablen für SSE und Streamable HTTP.

BetriebsartEinordnung bis 4.1.0
stdio (Standard, lokaler Prozess)Nicht betroffen. Der Aufrufer ist der Betreiber auf seinem eigenen Rechner, der Fix ändert dieses Verhalten nicht
SSE oder Streamable HTTP, MCP_AUTH_TOKEN gesetztBetroffen für jeden, der den Endpunkt erreicht und einen gültigen Auth-Header besitzt
SSE oder Streamable HTTP, kein MCP_AUTH_TOKENBetroffen für jeden, der den Endpunkt erreicht
Mit ALLOW_ONLY_READONLY_TOOLS=trueLaut Advisory nicht erreichbar, weil kubectl_patch nicht zu den freigegebenen Werkzeugen gehört. ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS=true schließt das Werkzeug dagegen nicht aus

Wie groß das Risiko im Einzelfall war, hängt davon ab, wer den Endpunkt erreichen konnte, und davon, welche Dateien auf dem Server-Host lagen. Die Advisory nennt als typische Ziele eine eingebundene Kubeconfig, den Token des Service-Accounts eines Pods und die Umgebungsvariablen des Prozesses.

Behebung und was Betreiber jetzt tun sollten

Was der Fix in 4.1.1 ändert

Pull Request #355 überträgt die bestehende Regel auf kubectl_patch: Läuft der Server über SSE oder Streamable HTTP, wird patchFile mit einer Fehlermeldung abgelehnt, die auf patchData verweist. Die Beschreibung des Parameters im Werkzeugschema nennt die Einschränkung jetzt ausdrücklich, wie bei den Geschwister-Werkzeugen. Das Verhalten im stdio-Modus bleibt unverändert. Außerdem ergänzt der Fix die bestehende Testdatei für Pfad-Parameter bei Netzwerk-Transporten um kubectl_patch, für beide Transport-Variablen.

Gerade der Test ist der nachhaltige Teil: Er schließt die Lücke in der Testabdeckung, durch die kubectl_patch von seinen Geschwistern abweichen konnte.

Empfehlungen für Betreiber

Die folgenden Schritte sind unsere Empfehlungen, keine Vorgaben der Maintainer.

SchrittMaßnahme
1. Version prüfenAuf 4.1.1 oder neuer aktualisieren. Die Advisory führt 4.1.1 als erste behobene Version.
2. Betriebsart klärenPrüfen, ob ENABLE_UNSAFE_SSE_TRANSPORT oder ENABLE_UNSAFE_STREAMABLE_HTTP_TRANSPORT gesetzt war. Wenn nicht, bestand der beschriebene Weg nicht.
3. Zugangsdaten erneuernLief ein Netzwerk-Transport, der für nicht vollständig vertrauenswürdige Aufrufer erreichbar war: Kubeconfig-Zugangsdaten und Service-Account-Token erneuern sowie Geheimnisse aus den Umgebungsvariablen des Prozesses austauschen.
4. Endpunkt abschirmenMCP_AUTH_TOKEN setzen, den Endpunkt nicht ungeschützt ins Netz stellen und TLS vorschalten, wie es die Projektdokumentation für den Produktivbetrieb empfiehlt.
5. Werkzeuge begrenzenNur die Werkzeuge freigeben, die wirklich gebraucht werden, etwa über ALLOW_ONLY_READONLY_TOOLS oder ALLOWED_TOOLS.
6. Rechte begrenzenDem Server nur die Cluster-Rechte geben, die die freigegebenen Werkzeuge brauchen, und keine fremden Geheimnisse auf seinem Host ablegen.

Zeitleiste

Aufgeführt sind nur Daten, die sich aus öffentlichen Quellen belegen lassen.

DatumEreignisBeleg
13.07.2026Pull Request #332: Pfad-Parameter von kubectl_create bei Netzwerk-Transport gesperrtGitHub-Commit
18.07.2026Pull Request #346: dieselbe Regel für kubectl_apply, kubectl_delete und HelmGitHub-Commit
26.07.2026Release 4.1.0, die letzte betroffene VersionGitHub-Release, npm
27.07.2026Quellcode-Prüfung auf Stand von 4.1.0, laut AdvisoryGitHub-Advisory
27.07.2026Fix gemergt (Pull Request #355), Release 4.1.1GitHub, npm
02.10.2026GHSA-6963-p4fp-2wxw mit CVE-2026-104776 veröffentlichtGitHub-Advisory
28.10.2026CVE-Eintrag bei MITRE noch nicht veröffentlichtAbfrage der CVE-Services-Schnittstelle

Die korrigierte Version stand damit mehr als zwei Monate vor der öffentlichen Beschreibung der Schwachstelle bereit.

Das Muster dahinter: Wenn einem Werkzeug die Prüfung seiner Geschwister fehlt

CVE-2026-104776 ist kein neuer Fehlertyp. Die Maintainer hatten die Gefahr erkannt, benannt und an vier Stellen behoben. Die Lücke lag in der fünften Stelle, die beim Nachziehen übersehen wurde. Wir nennen das Geschwister-Asymmetrie: Mehrere Werkzeuge haben dieselbe Form von Eingabe, aber nur ein Teil von ihnen prüft sie. Solche Fälle sind in MCP-Servern naheliegend, weil jedes Werkzeug eine eigene Datei mit eigener Eingabeverarbeitung ist und Schutzregeln oft pro Werkzeug eingebaut werden.

In unserer Erläuterung der OWASP MCP Top 10 berührt der Fall vor allem Klasse 10 (unsicherer Dateizugriff) und Klasse 7 (Zugangsdaten, die abfließen können). Dazu kommt ein Aspekt aus Klasse 4: Eine Schutzschicht, die alle Argumente sieht, aber nur Optionsnamen prüft, kann den Eindruck vollständiger Absicherung erwecken. Für Entwickler von MCP-Servern lassen sich daraus vier Regeln ableiten:

Für Betreiber gilt die Kehrseite: Ein MCP-Server mit Netzwerk-Transport ist ein Netzwerkdienst mit Zugriff auf Ihren Cluster und auf das Dateisystem seines Hosts. Er verdient dieselbe Behandlung wie jede andere API mit Geheimnissen, also Authentifizierung, minimale Rechte und eine bewusst kleine Werkzeugliste. Weitere öffentlich dokumentierte Funde finden Sie auf unserer Seite Forschung.

Dank an die Maintainer

Wir danken den Maintainern von mcp-server-kubernetes für die koordinierte Zusammenarbeit. Die Meldung lief vertraulich über die private Schwachstellenmeldung von GitHub. Die Maintainer haben den Fix mit Tests umgesetzt, die korrigierte Version lange vor der Veröffentlichung bereitgestellt und die Advisory mit CVE-Nummer und Nennung von CyberSec42 veröffentlicht. Bemerkenswert ist, wie nachvollziehbar das Projekt seine Sicherheitsentscheidungen dokumentiert: Die Begründung der Pfad-Sperre steht als Kommentar direkt im Code und in den Beschreibungen der Pull Requests.

Prüfen alle Werkzeuge Ihres MCP-Servers dasselbe?

Wir prüfen MCP-Server und KI-Agenten im schriftlich vereinbarten Umfang: ob Schutzregeln für alle Werkzeuge gleich gelten, welche Dateien und Zugangsdaten ein Werkzeugaufruf erreichen kann, wie die Transporte abgesichert sind und was ein Aufrufer tatsächlich bewirken kann. Jeder Befund kommt mit einem nachvollziehbaren Nachweis und einem konkreten Korrekturvorschlag. Mehr dazu unter KI-Pentest & MCP-Sicherheit.

KI-Pentest anfragen

CyberSec42 ist eine unabhängige technische Sicherheitsprüfung, keine akkreditierte Zertifizierungsstelle und keine Rechtsberatung. CyberSec42 steht in keiner Verbindung zu den Maintainern von mcp-server-kubernetes.

Häufige Fragen

Was ist CVE-2026-104776?

Eine Schwachstelle im MCP-Server mcp-server-kubernetes. Das Werkzeug kubectl_patch ließ über den Parameter patchFile Dateien auf dem Server-Host lesen, auch bei Betrieb über das Netzwerk, wo die Geschwister-Werkzeuge solche Pfade bereits ablehnten. Die GitHub-Advisory bewertet sie mit CVSS 7.1 (hoch).

Welche Versionen sind betroffen?

Laut Advisory alle Versionen bis einschließlich 4.1.0. Behoben ist die Schwachstelle in 4.1.1 vom 27.07.2026. Aktualisieren Sie auf 4.1.1 oder neuer.

Bin ich betroffen, wenn ich den Server über stdio nutze?

Nein. Die Prüfung greift nur, wenn der Server über SSE oder Streamable HTTP läuft. Im stdio-Modus ist der Aufrufer der Betreiber auf seinem eigenen Rechner, der Fix ändert dort nichts. Aktualisieren sollten Sie trotzdem, weil sich die Betriebsart später ändern kann.

Warum gibt es noch keinen Eintrag auf cve.org?

Die CVE-Nummer ist zugeteilt und in der GitHub-Advisory vermerkt. Der zugehörige Eintrag bei MITRE war bei unserer Abfrage am 28.10.2026 noch nicht veröffentlicht. Maßgeblich für Versionen und Bewertung ist bis dahin die GitHub-Advisory.

Wurde die Schwachstelle aktiv ausgenutzt?

Darüber treffen die öffentlichen Quellen keine Aussage. Unsere Prüfung war eine reine Quellcode-Analyse, bei der kein fremdes System angesprochen wurde.

Weiterlesen

Quellen