Abstrakte technische Illustration auf dunkelblauem Hintergrund: Ein leuchtender Eingangsanschluss an der linken Wand eines durchscheinenden Kastens nimmt eine einzelne dünne, blasse Linie auf, die kein Abzeichen und keinen Schlüssel trägt. Im Inneren des Kastens trifft die Linie auf einen Stapel kleiner, abgerundeter Paneele und verzweigt sich in eine kurze Reihe eckiger, befehlsähnlicher Striche, die nach unten in ein unteres Abteil verlaufen, das eine Ansammlung leuchtender, schlüsselförmiger Token enthält. Ein zweites, geschlossenes Tor, das hellblau umrandet ist, befindet sich neben dem Eingangsanschluss. Kein Text, keine Personen, keine Organisationslogos.
AI Safety Incidents

Ein einzelner unauthentifizierter POST an Bifrosts Management-API startete einen Befehl als Gateway-Benutzer

Autor

Magnus Corvin

Veröffentlicht am

Neueste Modelle · 20Alle Modelle ansehen →
Benchmarks: Artificial Analysis · täglich aktualisiert
Zurück zu allen Beiträgen

Am 14. September 2026 veröffentlichte JFrog Security Research CVE-2026-90898, eine Schwachstelle zur Befehlsausführung in Bifrost – dem von Maxim gepflegten Open-Source-KI-Gateway – und bewertete sie mit 9,8 von 10. Der Angriff bestand aus einer einzigen HTTP-Anfrage. Ein unauthentifizierter POST /api/mcp/client registriert einen stdio-MCP-Client; Bifrost liest ihn als Programmnamen plus Argumentliste und startet ihn sofort, noch vor jedem MCP-Handshake, als den Benutzer, unter dem das Gateway läuft; im offiziellen Image ist dieser Benutzer appuser. Ein Gateway ist außerdem der Ort, an dem die Provider-Schlüssel und virtuellen Schlüssel eines Betreibers liegen, sodass ein dort laufender Prozess an die Anmeldedaten gelangt. Was die Anfrage anonym machte, war eine mitgelieferte Standardeinstellung: governance.auth_config.is_enabled ist false, und, in der Formulierung von JFrog, „ist die Authentifizierung aus, ist jeder Aufrufer ein lokaler Administrator“. Keine zitierte Quelle berichtet, dass die Schwachstelle jemals ausgenutzt wurde. Die eigenen Quellen des Eintrags, seine Schweregradbewertung und seine Einschätzung der Vertrauenswürdigkeit befinden sich in dem KI-Vorfallarchiv, zusammen mit den anderen dokumentierten KI-Gateway- und MCP-Schwachstellen des vergangenen Jahres.

Bifrost ist ein einziger Dienst, der zwischen einer Anwendung und den von ihr aufgerufenen Sprachmodellen sitzt. Sein Repository beschreibt es als ein quelloffenes, unter Apache-2.0 lizenziertes Gateway, das „den Zugriff auf 23+ Anbieter ... über eine einzige OpenAI-kompatible API vereint“, wobei MCP-Proxying, virtuelle Schlüssel, Budgets und Lastverteilung pro Anbieter zu seinen Funktionen gehören, und es hatte am 28. Oktober 2026 rund 9.150 GitHub-Sterne. Diese Kombination ist der eigentliche Grund, warum eine Shell auf diesem speziellen Host einen kritischen Score rechtfertigt: Der Prozess, der die Anfragen weiterleitet, ist zugleich der Prozess, der die Zugangsdaten für jeden Upstream besitzt, an den er weiterleitet. The Hacker News berichtete am 22. September über den Fehler und brachte die Konsequenz unmissverständlich auf den Punkt – weil das Gateway die API-Schlüssel für jeden verbundenen Anbieter speichert, verschafft die Ausführung von Befehlen im Gateway-Prozess dem Angreifer Zugriff auf diese Zugangsdaten.

Der gesamte Angriff war ein einziger POST

JFrogs Sicherheitshinweis, veröffentlicht unter der Referenz JFSA-2026-001686326, beschreibt einen Endpoint, der dazu dient, einem Administrator das Hinzufügen eines MCP-Servers zu ermöglichen. Ein stdio-Client in der MCP-Spezifikation ist keine URL; er ist ein Befehl mit seinen Argumenten, den das Hostprogramm starten soll. Bifrost akzeptiert diese Konfiguration über die Management-API und startet das Programm, sobald der Client hinzugefügt wird. Keine Capability-Aushandlung, keine Prüfung der Serveridentität, kein Handshake muss zuerst erfolgreich sein – der Sicherheitshinweis stellt ausdrücklich klar, dass der Handshake nicht das ist, was den Prozess startet.

Der Proof of Concept im Advisory ist ein kurzer JSON-Body, der an ein Gateway gesendet wird, wobei die Authentifizierung auf ihrem Standardwert belassen wurde. Er registriert einen Client, dessen Befehl /bin/sh ist und dessen Argumente eine Markerdatei schreiben, und liest den Marker anschließend wieder aus. JFrog ergänzt ein operatives Detail, das bei der Incident Response wichtig ist: Die HTTP-Anfrage kann in ein Timeout laufen, während Bifrost auf einen Handshake wartet, der nie erfolgt, und ein Timeout in den Logs bedeutet nicht, dass der Befehl nicht gestartet wurde. Der Prozess läuft zu diesem Zeitpunkt bereits.

Der CVE-Eintrag, von JFrog als CVE Numbering Authority vergeben, ordnet den Fehler den Kategorien CWE-306, fehlende Authentifizierung für eine kritische Funktion, und CWE-284, unzureichende Zugriffskontrolle, zu und benennt die beiden Dateien, die den Handler und seine Middleware enthalten: transports/bifrost-http/handlers/mcp.go und transports/bifrost-http/handlers/middlewares.go. Das betroffene Modul ist github.com/maximhq/bifrost/transports, unter Linux und macOS, für alle Versionen unter 2.1.0.

Die Voreinstellung, die die Anfrage anonymisierte

Nichts davon wäre ohne eine zweite Bedingung ausnutzbar, und die zweite Bedingung ist die eigene Standardeinstellung des Produkts. Die Management-Authentifizierungs-Middleware von Bifrost wird durch governance.auth_config.is_enabled gesteuert, das standardmäßig auf false steht. Ist sie deaktiviert, behandelt die Middleware jeden Aufrufer als lokalen Administrator – die Zusammenfassung des Advisories selbst besagt, dass deaktivierte Authentifizierung bedeutet, dass jeder Aufrufer ein lokaler Admin ist – daher war die Prüfung, die die Anfrage hätte stoppen können, nie im Pfad.

Der Fix, Pull Request #6757, wurde am 2. September 2026 in das Projekt gemergt, zwölf Tage bevor die CVE veröffentlicht wurde, und sechs Tage vor dem Release, das sie enthält. Seine Beschreibung ist ungewöhnlich offen hinsichtlich der Gestalt des Problems: Der Pull Request schließt zwei Primitive für nicht authentifizierten Zugriff in derselben Registrierungs-API, nicht nur eines. Das erste ist der stdio-Client. Das zweite ist ein http- oder sse-MCP-Client, der auf eine Loopback- oder private Netzwerkadresse zeigt, was der Pull Request als SSRF-Primitive gegen interne Dienste bezeichnet, „einschließlich des Cloud-Metadaten-Endpunkts 169.254.169.254“. Beide werden jetzt mit HTTP 403 abgelehnt, wenn die Anfrage den Handler ohne eine echte Anmeldedatenprüfung erreicht. Authentifizierte Administratoren behalten beide Fähigkeiten, und Betreiber können stdio-Clients weiterhin über config.json bereitstellen.

Dieses zweite Primitiv erscheint nicht im CVE-Text. Es steht im Patch, und es ist der Grund, warum die Behebung ein Gate statt einer Entfernung ist: Die Funktion war nie der Fehler. Einen nicht authentifizierten Aufrufer als Administrator zu behandeln, war es.

Wo die Management-API tatsächlich lauschte

Die Erreichbarkeit ist der Teil der Dokumentation, den die Quellen am konsistentesten beschreiben und am wenigsten messen. Das Advisory von JFrog gibt für das unveränderte Binary localhost:8080 als Standard an, was einen Angreifer auf den Host selbst beschränkt. Das Advisory desselben Teams für die begleitende Schwachstelle gibt an, dass das offizielle Docker-Image stattdessen an 0.0.0.0 bindet, und The Hacker News wiederholt dies: Das Image macht die Management-API von außerhalb des Containers erreichbar, wenn der Port veröffentlicht wird. Die Quickstart-Anleitung in Bifrosts eigener README verwendet „docker run -p 8080:8080 maximhq/bifrost“, und Dockers -p veröffentlicht einen Container-Port auf jeder Host-Schnittstelle, sofern keine Adresse angegeben wird. Das GitHub-Advisory für die Schwachstelle hält fest, dass der gemeldete Pfad gegen das veröffentlichte Image maximhq/bifrost:latest verifiziert wurde, wobei eine nicht authentifizierte Anfrage /bin/sh startete und als appuser eine Markerdatei schrieb.

Was keine Quelle liefert, ist eine Zahl. Es gibt keine Zählung internetseitig erreichbarer Bifrost-Instanzen, kein Scan-Ergebnis, keine Telemetrie und kein Opfer. Der Bericht belegt keinen tatsächlichen Schaden, und dieses Fehlen ist eine Tatsache über die Berichterstattung und keine Beruhigung — die Schwachstellenklasse ist nur dort gefährlich, wo zwei Bedingungen zusammentreffen: ein exponierter Listener und eine unveränderte Standardeinstellung, und niemand hat veröffentlicht, wie oft beides zutraf.

Ein Endpunkt, zwei Schwachstellen, eine Grundursache

Acht Tage vor dem MCP-Advisory, am 6. September 2026, veröffentlichte dasselbe Forschungsteam CVE-2026-86242, einen zweiten nicht authentifizierten Pfad in denselben Prozess. Er wurde von Or Peles gefunden und mit 8,1 bewertet und missbraucht POST /api/plugins: Bifrost akzeptiert ein aktiviertes benutzerdefiniertes Plugin, dessen Pfad eine HTTP-URL ist; der Shared-Object-Loader behandelt einen Pfad mit http-Präfix als Download, schreibt den Inhalt in eine temporäre .so-Datei und übergibt diese Datei an Go's plugin.Open. Wenn das Laden erfolgreich ist, wird eine optionale Init-Funktion sofort mit der Konfiguration des Angreifers ausgeführt, und zwar als Gateway-Benutzer.

Die Build-Variante entscheidet, was ein Angreifer erhält. Bei den dynamisch gelinkten Builds, die das Projekt für benutzerdefinierte Go-Plugins dokumentiert, wird erwartet, dass das Laden erfolgreich ist, was der Advisory als nicht authentifizierte Remote-Codeausführung bezeichnet. Beim veröffentlichten statisch gelinkten Docker-Image schlägt plugin.Open mit „Dynamic loading not supported“ fehl, sodass dieselbe Anfrage zu Server-Side Request Forgery herabgestuft wird. Ein ladbares Plugin muss außerdem zur Go-Version, zum Betriebssystem, zur Architektur und zur Verlinkung des Hosts passen, was eine echte Einschränkung und keine Formsache ist. Der Fix ist transports/v2.0.0 über Pull Request #5763, und der betroffene Bereich umfasst alles darunter.

Die Falle ist die Release-Reihenfolge. v2.0.0 behebt den Plugin-Pfad und behebt den MCP-Pfad nicht — The Hacker News sagt das ausdrücklich, und das MCP-Advisory von JFrog bestätigt, dass v2.0.0 weiterhin die unauthentifizierte stdio-Registrierung erlaubt. Ein Betreiber, der nach dem Advisory vom 6. September zeitnah gepatcht hat, war allein wegen dieses Punktes noch gefährdet, bis transports/v2.1.0 am 8. September ausgeliefert wurde. Beide Schwachstellen laufen in beiden Advisories und im eigenen Pull Request des Anbieters auf denselben Satz hinaus: Authentifizierung deaktiviert ist die Voreinstellung.

Was die Quellen belegen – und was nicht

Der Mechanismus, der Versionsbereich, die Behebung und die Anerkennung stimmen im Advisory, im von JFrog zugewiesenen CVE-Eintrag, im eigenen Pull Request und in den Release Notes des Projekts sowie in The Hacker News überein. Die verbleibende Uneinigkeit betrifft den Schweregrad, und sie ist real.

Die 9.8 ist JFrogs Bewertung als zuweisende CNA und die Bewertung, die NVD übernimmt – der NVD-Eintrag führt reefs@jfrog.com als Quelle der Metrik und zeigt den Eintrag mit Stand vom 28. Oktober 2026 weiterhin im Status „Awaiting Analysis“, was bedeutet, dass NVD den Vektor des Zuweisers veröffentlicht hat statt seiner eigenen Analyse davon. Die demselben Eintrag beigefügte SSVC-Bewertung des CISA Coordinator, mit Zeitstempel vom 14. September 2026, gibt Ausnutzung mit „none“, Automatisierbarkeit mit „yes“ und technische Auswirkung mit „total“ an. Das EPSS-Modell von FIRST bezifferte die Wahrscheinlichkeit einer Ausnutzung in den nächsten 30 Tagen am 27. Oktober 2026 auf 2,3 Prozent, im 83. Perzentil aller bewerteten CVEs, und weder diese CVE noch CVE-2026-86242 ist im CISA-Katalog „Known Exploited Vulnerabilities“ mit Stand vom 27. Oktober 2026 aufgeführt.

Dagegen bestreitet Maxim die Bewertung. In einer Erklärung gegenüber The Hacker News sagte Akshay Deo, Chief Technology Officer und Mitbegründer des Unternehmens, das praktische Risiko sei geringer, als der kritische Score vermuten lasse, denn eine Ausnutzung setze voraus, dass die Verwaltungsschnittstelle aus einem nicht vertrauenswürdigen Netzwerk erreichbar sei und der Betreiber die Authentifizierung nicht gesetzt gelassen habe; die standardmäßige und dokumentierte Bereitstellung, so sagte er, platziere das Gateway in einem privaten Netzwerk. The Hacker News berichtet, dass Maxim die Schwachstelle als Schwachstelle mit geringem Schweregrad einstuft und mit JFrog, das die CVE vergeben hat, an einer Überarbeitung der Bewertung arbeitet. Diese Aussage findet sich in jenem einen Medium; es wurde keine zweite Veröffentlichung gefunden, die Maxims Position zitiert, und bis zum 28. Oktober 2026 war keine Überarbeitung veröffentlicht worden — der CVE-Eintrag wurde zuletzt am 14. September aktualisiert und der NVD-Eintrag am 18. September, beide weiterhin bei 9.8.

Zwei weitere Diskrepanzen sollten benannt und nicht übergangen werden. Die GitHub-Advisories des Projekts, veröffentlicht am 23. September 2026 und mit dem Forscher von JFrog als Melder genannt, nennen weiterhin 9.8 für die MCP-Schwachstelle und 8.1 für die Plugin-Schwachstelle, ohne Hinweis auf die von Maxim beschriebene Revision. Und die betroffenen Bereiche in diesen Advisories beziehen sich auf Go-Modulversionen – unter 1.5.27 und unter 1.6.3 – statt auf die Release-Tags von Transports, die die JFrog-Advisories verwenden; ein Betreiber, der ein Dokument mit dem anderen abgleicht, muss daher erst zwei Nummerierungsschemata in Einklang bringen, bevor er entscheiden kann, ob ein Build betroffen ist.

Rendered two-column card with the kicker 'BIFROST · CVE-2026-90898' and the title 'What the sources establish — and what they do not', subtitled 'Sources: JFrog JFSA-2026-001686326 (14 September 2026), the CVE record assigned by JFrog, NVD, FIRST EPSS, the CISA KEV catalogue, and the project's pull request 6757 and release tags.' The left column, headed 'ESTABLISHED' in blue, lists eight items: score 9.8 with the vector AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H supplied by the CNA; CWE-306 missing authentication with CWE-284 access control; unauthenticated POST /api/mcp/client starting a program as the gateway user; affected below transports 2.1.0 when management auth is disabled, the default; fixed in transports 2.1.0, PR 6757 merged 2 September, released 8 September 2026; CISA SSVC of 14 September 2026 with exploitation none, automatable yes, impact total; EPSS 2.3 percent at the 83rd percentile on 27 October 2026; and not in the CISA KEV catalogue dated 27 October 2026. The right column, headed 'NOT ESTABLISHED, OR CONTESTED' in amber, lists eight items: no exploitation reported, and the archive records real harm as false; no count of exposed or affected deployments in any cited source; severity contested, the vendor's CTO telling The Hacker News it is low; no published revision to the score as of 28 October 2026; NVD still Awaiting Analysis, so the 9.8 is the assigner's and not NVD's; affected ranges stated in two numbering schemes across the advisories; no detection or triage guidance in either advisory; and no evidence tying the flaw to any intrusion. A footer reads 'Card rendered by OrcaRouter'. The OrcaRouter logo is composited in the bottom-right corner.

Was sich geändert hat – und was die Betreiber tun sollten

Die Chronologie verläuft von der Offenlegung aus rückwärts, was der am wenigsten intuitive Teil der Aufzeichnung ist. Pull Request #6757 wurde am 2. September 2026 zusammengeführt. transports/v2.1.0, die Version, die im Sicherheitshinweis als erste mit der Fehlerbehebung genannt wird, wurde am 8. September veröffentlicht – sechs Tage bevor CVE-2026-90898 am 14. September veröffentlicht wurde. Die Plugin-Korrektur des Projekts ging seinem eigenen Sicherheitshinweis auf dieselbe Weise voraus: transports/v2.0.0 wurde am 26. August ausgeliefert, elf Tage vor der CVE vom 6. September. Betreiber, die Releases statt Feeds verfolgen, hatten die Patches bereits, bevor sie die Warnungen erhielten.

Was das Upgrade bringt, ist eng begrenzt und spezifisch. Ab 2.1.0 gibt eine nicht authentifizierte stdio-Registrierung 403 zurück, und der Befehl startet nicht; authentifizierte Administratoren behalten die Funktion, und die Bereitstellung über config.json funktioniert weiterhin. Die Übergangslösung des Advisories für alle, die nicht wechseln können, besteht darin, governance.auth_config.is_enabled auf true zu setzen, starke Administrator-Anmeldedaten zu verwenden und den Management-Listener von nicht vertrauenswürdigen Netzwerken fernzuhalten. JFrogs Anweisung für Instanzen, die ohne Authentifizierung exponiert betrieben wurden, lautet nicht, zu untersuchen und zu hoffen: Behandeln Sie sie als kompromittiert und rotieren Sie virtuelle Schlüssel und Provider-Anmeldedaten.

Der Teil, der am ehesten falsch gelesen wird, ist die Versionsarithmetik. v2.0.0 behebt diesen Fehler nicht. Auch die Reihe 1.6.x bis einschließlich 1.6.11 enthält die Korrektur nicht, und das neueste Tag der 1.6-Serie des Projekts ist transports/v1.6.11, veröffentlicht am 14. August 2026; Stand 28. Oktober 2026 gibt es im Repository keine 1.7-Reihe – daher gibt es innerhalb dieser Serie kein gepatchtes Release, und Betreiber von 1.6.x müssen auf 2.1.0 oder später wechseln, statt auf einen Backport zu warten. Die aktuelle Release-Reihe liegt weit jenseits dieses Punkts: transports/v2.3.2 wurde am 20. Oktober 2026 veröffentlicht.

Rendered release-timeline card with the kicker 'BIFROST · RELEASE TIMELINE', the title 'The fix shipped six days before the advisory' and the subtitle 'Dates from the project's release tags and pull request metadata, the JFrog advisories and The Hacker News. Every date below is a single day.' A horizontal timeline carries seven dated markers: 26 Aug 2026, transports 2.0.0 published; 2 Sep 2026, PR 6757 merged; 6 Sep 2026, CVE-2026-86242 published, 8.1; 8 Sep 2026, transports 2.1.0, the fix; 14 Sep 2026, CVE-2026-90898 published, 9.8; 22 Sep 2026, vendor statement reported; 23 Sep 2026, GitHub advisories published. Below it, three bars show release lines: a hatched amber bar labelled '1.6.x line' reading 'affected — no patched release in the series; newest tag 1.6.11, 14 August 2026'; a bar labelled '2.0.0' split between a pale blue segment reading 'plugin flaw fixed' and a red segment reading 'MCP flaw still open'; and a solid blue bar labelled '2.1.0 and later' reading 'MCP fix — unauthenticated stdio registration returns 403'. A foot band headed 'THE PART THAT IS EASY TO GET WRONG' notes that 2.0.0 was the patched release on 6 September and did not close the MCP path, that for the two days before 2.1.0 an operator who patched on the day of the warning was still exposed, and that the 1.6.x series has no fixed release at all. A footer reads 'Card rendered by OrcaRouter'. The OrcaRouter logo is composited in the bottom-right corner.

Nach der Veröffentlichung sind zwei Dinge passiert, die ein Verteidiger nutzen kann. Die GitHub-Sicherheitshinweise des Projekts – GHSA-86gf-xh3g-rvxq für die MCP-Schwachstelle mit Einstufung „kritisch“ und GHSA-2qp8-4xgm-fw6g für die Plugin-Schwachstelle mit Einstufung „hoch“ – wurden am 23. September 2026 veröffentlicht, wodurch die Dependency- und Advisory-Feeds eine zweite Kennung zum Abgleich erhielten. Und am 13. Oktober 2026 wurde eine Erkennungsvorlage für CVE-2026-90898 in das öffentliche Repository nuclei-templates gemergt, was bedeutet, dass die Prüfung auf einen unauthentifizierten Registrierungsversuch jetzt etwas ist, das eine Scanning-Pipeline ausführen kann, statt etwas, das jedes Team selbst schreiben muss.

Abstract illustration on a dark navy field: a wide translucent slab representing a credential store, filled with evenly spaced glowing key-shaped tokens, stands behind a low wall. A narrow gateway aperture in the wall holds a fresh, brighter set of tokens, a blank card-shaped slip lies pushed aside on the ground in front of it, and a thin amber arc sweeps from the aperture around to the store. A second gateway aperture in the background remains closed and unlit. No text, no people, no organisation logos.

Offen bleibt die Schweregradbewertung, und ob sie geklärt wird, entscheiden die beiden Organisationen, die noch darüber im Gespräch sind. Maxims Position, wie berichtet wird, ist, dass eine 9,8 eine Schwachstelle überbewertet, die einen exponierten Listener und eine nicht gesetzte Standardeinstellung benötigt, um relevant zu sein – eine Behauptung, die grundsätzlich prüfbar und öffentlich ungeprüft ist, weil niemand veröffentlicht hat, wie viele Bereitstellungen diese beiden Bedingungen erfüllten. JFrogs Position ist die Bewertung, die es als CNA vergeben hat und die im CVE-Eintrag und in NVD weiterhin Bestand hat. Bis eine von ihnen eine Revision veröffentlicht, ist die operative Lesart so oder so dieselbe: Die Schwachstelle ist real und wurde Ende zu Ende auf dem veröffentlichten Container-Image verifiziert, der Fix wurde vor der Warnung ausgeliefert, die 1.6-Reihe hat überhaupt keinen Fix, und jede Instanz, die mit deaktivierter Authentifizierung auf einem erreichbaren Listener lief, sollte als Zugangsdaten-Vorfall behandelt werden und nicht als ein einzuplanender Patch.