
Jeden nieuwierzytelniony POST do API zarządzania Bifrost uruchomił polecenie jako użytkownik bramy
- OrcaNOWOŚĆOrcaCyber: GLM 5.3 Flash Abliterated2026-10-2795 tok/s
- OrcaNOWOŚĆOrcaCyber: Qwen3.8 Flash Next Abliterated2026-10-26$0.80 / $1.60 za 1 mln tokenów · 249 tok/s
- OrcaNOWOŚĆOrcaCyber: MiMo V2.6 Flash Abliterated2026-10-26$0.80 / $1.60 za 1 mln tokenów · 86 tok/s
- MoonshotNOWOŚĆMoonshotAI: Kimi K3.1 Pro2026-10-2455Inteligencja
- OrcaNOWOŚĆOrcaCyber: DeepSeek V4.1 Flash Abliterated2026-10-23$0.80 / $1.60 za 1 mln tokenów · 109 tok/s
- minimaxNOWOŚĆMiniMax: M3.1 Flash2026-10-1943Inteligencja
- OrcaNOWOŚĆOrca: OrcaCyber Ultra 1.02026-10-17$5.00 / $10.00 za 1 mln tokenów · 51 tok/s
- deepseekNOWOŚĆDeepSeek: DeepSeek V4.1 Flash 10172026-10-1745Inteligencja
- DeepSeekNOWOŚĆDeepSeek: DeepSeek V4.1 Flash2026-10-1740Inteligencja
- OrcaOrca: OrcaCyber Zero 1.52026-10-10$3.00 / $7.50 za 1 mln tokenów · 114 tok/s
- openaiOpenAI: GPT-6.1 Sol2026-09-2952Inteligencja
- anthropicAnthropic: Claude Sonnet 5.52026-09-2856Inteligencja
- typesafeTypeSafe: Jev 1.132026-09-24$0.04 / $0.00 za 1 mln tokenów · 120 tok/s
- OpenAIOpenAI: GPT-6 Luna2026-09-2238Inteligencja
- OpenAIOpenAI: GPT-6 Sol2026-09-2248Inteligencja
- AnthropicAnthropic: Claude Opus 5.52026-09-2258Inteligencja
- xiaomiXiaomi: MiMo-V2.6-Flash2026-09-2138Inteligencja
- xiaomiXiaomi: MiMo-V2.6-Pro2026-09-2146Inteligencja
- xAIGrok 4.72026-09-2146Inteligencja
- OrcaOrca: OrcaCyber Zero 1.02026-09-17$3.00 / $7.50 za 1 mln tokenów · 191 tok/s
14 września 2026 r. JFrog Security Research opublikował CVE-2026-90898, lukę umożliwiającą wykonanie poleceń w Bifrost — otwartoźródłową bramę AI utrzymywaną przez Maxim — i ocenił ją na 9,8 na 10. Atak polegał na jednym żądaniu HTTP. Nieuwierzytelnione żądanie POST /api/mcp/client rejestruje klienta stdio MCP, który Bifrost odczytuje jako nazwę programu wraz z listą argumentów i uruchamia natychmiast, przed jakimkolwiek uzgadnianiem MCP, jako użytkownik uruchamiający bramę; w oficjalnym obrazie tym użytkownikiem jest appuser. Brama jest też miejscem, w którym znajdują się klucze dostawców i klucze wirtualne operatora, więc proces tam uruchomiony ma dostęp do poświadczeń. Anonimowość żądania zapewniało domyślne ustawienie dostarczane wraz z produktem: governance.auth_config.is_enabled ma wartość false, a według sformułowania JFrog „wyłączenie uwierzytelniania oznacza, że każdy wywołujący jest lokalnym administratorem”. Żadne z cytowanych źródeł nie podaje, by luka została kiedykolwiek wykorzystana. Źródła samego rekordu, ocena ważności i ocena pewności znajdują się w archiwum incydentów AI, obok innych udokumentowanych w ostatnim roku luk w bramach AI i MCP.
Bifrost to pojedyncza usługa, która znajduje się pomiędzy aplikacją a modelami językowymi, które wywołuje. Jej repozytorium opisuje ją jako bramę typu open source na licencji Apache-2.0, która „ujednolica dostęp do 23+ dostawców ... poprzez jedno API kompatybilne z OpenAI”, a wśród jej funkcji są proxowanie MCP, klucze wirtualne, budżety i równoważenie obciążenia dla poszczególnych dostawców; na dzień 28 października 2026 r. miała około 9 150 gwiazdek na GitHubie. Ta kombinacja jest całym powodem, dla którego powłoka na tym konkretnym hoście zasługuje na krytyczną ocenę: proces, który kieruje żądaniami, jest także procesem, który przechowuje poświadczenia dla każdego systemu upstream, do którego kieruje żądania. Hacker News, informując o tej wadzie 22 września, ujął konsekwencję wprost — ponieważ brama przechowuje klucze API dla każdego podłączonego dostawcy, wykonywanie poleceń w procesie bramy daje atakującemu dostęp do tych poświadczeń.
Cały atak był pojedynczym żądaniem POST
Biuletyn bezpieczeństwa JFrog, opublikowany pod numerem referencyjnym JFSA-2026-001686326, opisuje punkt końcowy, którego celem jest umożliwienie administratorowi dodania serwera MCP. Klient stdio w specyfikacji MCP nie jest adresem URL; to polecenie i jego argumenty, które program hosta ma uruchomić. Bifrost przyjmuje tę konfigurację przez API zarządzania i uruchamia program, gdy tylko klient zostanie dodany. Żadne uzgadnianie możliwości, żadna weryfikacja tożsamości serwera, żaden handshake nie musi się najpierw zakończyć sukcesem — biuletyn wyraźnie stwierdza, że to nie handshake uruchamia proces.
Dowód koncepcji w biuletynie to krótkie ciało JSON wysyłane do bramy z uwierzytelnianiem pozostawionym w ustawieniu domyślnym. Rejestruje ono klienta, którego poleceniem jest /bin/sh, a którego argumenty zapisują plik znacznikowy, po czym odczytuje ten znacznik z powrotem. JFrog dodaje szczegół operacyjny istotny podczas reagowania na incydenty: żądanie HTTP może zakończyć się przekroczeniem limitu czasu, gdy Bifrost czeka na handshake, który nigdy nie nadchodzi, a przekroczenie limitu czasu w logach nie oznacza, że polecenie nie zostało uruchomione. Proces już wtedy działa.
Rekord CVE, przypisany przez JFrog jako CVE Numbering Authority, przyporządkowuje defekt do CWE-306, brak uwierzytelniania dla funkcji krytycznej, oraz CWE-284, nieprawidłowa kontrola dostępu, oraz wskazuje dwa pliki zawierające handler i jego middleware: transports/bifrost-http/handlers/mcp.go i transports/bifrost-http/handlers/middlewares.go. Dotknięty moduł to github.com/maximhq/bifrost/transports, w systemach Linux i macOS, dla wszystkich wersji poniżej 2.1.0.
Domyślne ustawienie, które sprawiło, że żądanie stało się anonimowe
Nic z tego nie byłoby możliwe do wykorzystania bez drugiego warunku, a drugi warunek to domyślne ustawienie samego produktu. Oprogramowanie pośredniczące uwierzytelniania zarządzania Bifrost jest ograniczane przez governance.auth_config.is_enabled, które domyślnie ma wartość false. Gdy jest wyłączone, oprogramowanie pośredniczące traktuje każdego wywołującego jako lokalnego administratora — streszczenie samego biuletynu mówi, że wyłączenie uwierzytelniania oznacza, iż każdy wywołujący jest lokalnym administratorem — więc sprawdzenie, które powstrzymałoby żądanie, nigdy nie znalazło się na ścieżce.
Poprawka, pull request #6757, została scalona z projektem 2 września 2026 r., dwanaście dni przed publikacją CVE i sześć dni przed wydaniem, które ją zawiera. Jej opis jest niezwykle szczery co do charakteru problemu: pull request zamyka dwa mechanizmy nieuwierzytelnionego dostępu w tym samym API rejestracji, a nie jeden. Pierwszy to klient stdio. Drugi to klient MCP http lub sse wskazujący na adres pętli zwrotnej lub w sieci prywatnej, który pull request nazywa prymitywem SSRF wymierzonym w usługi wewnętrzne, „w tym w punkt końcowy metadanych chmury 169.254.169.254”. Oba są teraz odrzucane z kodem HTTP 403, gdy żądanie dociera do handlera bez rzeczywistej weryfikacji poświadczeń. Uwierzytelnieni administratorzy zachowują obie możliwości, a operatorzy nadal mogą aprowizować klientów stdio przez config.json.
Ten drugi prymityw nie pojawia się w tekście CVE. Jest w łatce i to dlatego poprawka działa jak bramka, a nie jak usunięcie: funkcja nigdy nie była błędem. Błędem było traktowanie nieuwierzytelnionego wywołującego jako administratora.
Gdzie faktycznie nasłuchiwał interfejs API zarządzania
Osiągalność to ta część zapisu, którą źródła opisują najspójniej, a mierzą najrzadziej. Biuletyn JFrog podaje, że domyślnym ustawieniem standardowego pliku binarnego jest localhost:8080, co ogranicza atakującego do samego hosta. Biuletyn tego samego zespołu dotyczący towarzyszącej luki stwierdza, że oficjalny obraz Dockera wiąże zamiast tego 0.0.0.0, a The Hacker News to powtarza: obraz udostępnia API zarządzania z zewnątrz kontenera, jeśli port zostanie opublikowany. Szybki start w README samego Bifrosta uruchamia „docker run -p 8080:8080 maximhq/bifrost”, a opcja -p Dockera publikuje port kontenera na wszystkich interfejsach hosta, chyba że podano adres. Biuletyn GitHub dotyczący luki odnotowuje, że zgłoszona ścieżka została zweryfikowana na opublikowanym obrazie maximhq/bifrost:latest, gdzie nieuwierzytelnione żądanie uruchomiło /bin/sh i zapisało znacznik jako appuser.
Żadne źródło nie podaje liczby. Nie ma licznika instancji Bifrost wystawionych do internetu, żadnego wyniku skanowania, żadnej telemetrii ani żadnej ofiary. W materiale nie ma rzeczywistej szkody, a ten brak jest faktem dotyczącym sposobu raportowania, a nie pocieszeniem — ta klasa podatności jest niebezpieczna tylko tam, gdzie zbiegają się dwa warunki: wystawiony nasłuchujący punkt końcowy i nietknięte ustawienie domyślne, i nikt nie opublikował, jak często występowały one jednocześnie.
Jeden endpoint, dwie wady, jedna przyczyna źródłowa
Osiem dni przed biuletynem bezpieczeństwa MCP, 6 września 2026 r., ten sam zespół badawczy opublikował CVE-2026-86242, drugą nieuwierzytelnioną ścieżkę do tego samego procesu. Odkryta przez Or Peles i oceniona na 8,1, wykorzystuje POST /api/plugins: Bifrost akceptuje włączoną wtyczkę niestandardową, której ścieżka jest adresem URL HTTP; program ładujący obiekty współdzielone traktuje ścieżkę z prefiksem http jako pobieranie, zapisuje treść do tymczasowego pliku .so i przekazuje ten plik do plugin.Open języka Go. Jeśli ładowanie się powiedzie, opcjonalna funkcja Init uruchamia się natychmiast z konfiguracją atakującego, jako użytkownik bramy.
Wariant kompilacji decyduje o tym, co otrzyma atakujący. W przypadku kompilacji z dynamicznym linkowaniem, które projekt dokumentuje dla niestandardowych wtyczek Go, oczekuje się, że ładowanie się powiedzie, co biuletyn określa jako nieuwierzytelnione zdalne wykonanie kodu. W opublikowanym statycznie linkowanym obrazie Docker plugin.Open kończy się niepowodzeniem z komunikatem „Dynamic loading not supported”, więc to samo żądanie degraduje się do fałszowania żądań po stronie serwera. Ładowalna wtyczka musi również odpowiadać wersji Go, systemowi operacyjnemu, architekturze i sposobowi linkowania hosta, co jest rzeczywistym ograniczeniem, a nie formalnością. Poprawka to transports/v2.0.0, wprowadzona przez pull request #5763, a zakresem objętym problemem jest wszystko poniżej.
Pułapka tkwi w kolejności wydań. v2.0.0 naprawia ścieżkę pluginu, ale nie naprawia ścieżki MCP — The Hacker News mówi to wprost, a biuletyn doradczy JFrog dotyczący MCP potwierdza, że v2.0.0 nadal pozwala na nieuwierzytelnioną rejestrację stdio. Operator, który załatał system szybko po biuletynie z 6 września, był przez sam ten fakt nadal narażony aż do wydania transports/v2.1.0 8 września. Obie wady sprowadzają się do tego samego zdania w obu biuletynach i we własnym pull requeście dostawcy: uwierzytelnianie jest domyślnie wyłączone.
Co źródła ustalają, a czego nie
Mechanizm, zakres wersji, poprawka i uznanie zasług są zgodne w biuletynie zabezpieczeń, rekordzie CVE przypisanym przez JFrog, własnym pull requeście i informacjach o wydaniu projektu oraz w The Hacker News. Pozostała rozbieżność dotyczy poziomu istotności i jest realna.
Wartość 9.8 to ocena JFrog jako przydzielającego CNA i jest to ocena, którą podaje NVD — rekord NVD wskazuje reefs@jfrog.com jako źródło metryki i, na dzień 28 października 2026 r., nadal wyświetla wpis ze statusem „Awaiting Analysis”, co oznacza, że NVD opublikowało wektor przydzielającego, a nie własną analizę. Ocena SSVC koordynatora CISA dołączona do tego samego rekordu, z datą 14 września 2026 r., wskazuje eksploatację „none”, automatyzowalność „yes” i wpływ techniczny „total”. Model EPSS FIRST określił prawdopodobieństwo eksploatacji w ciągu najbliższych 30 dni na 2,3 procent na dzień 27 października 2026 r., co plasuje je w 83. percentylu wśród wszystkich ocenionych CVE, a ani to CVE, ani CVE-2026-86242 nie występuje w katalogu CISA Known Exploited Vulnerabilities z datą 27 października 2026 r.
W przeciwieństwie do tego Maxim kwestionuje tę ocenę. W oświadczeniu dla The Hacker News Akshay Deo, dyrektor ds. technologii i współzałożyciel firmy, powiedział, że praktyczne ryzyko jest niższe, niż sugeruje krytyczna ocena, ponieważ wykorzystanie wymaga, aby interfejs zarządzania był osiągalny z niezaufanej sieci, a operator pozostawił uwierzytelnianie nieustawione; jego zdaniem domyślne i udokumentowane wdrożenie umieszcza bramę w sieci prywatnej. The Hacker News donosi, że Maxim uznaje tę lukę za niskiej wagi i współpracuje z JFrog, które przypisało CVE, nad zmianą oceny. To oświadczenie pojawia się w tym jednym serwisie; nie znaleziono drugiej publikacji cytującej stanowisko Maxima, a do 28 października 2026 r. nie opublikowano żadnej rewizji — rekord CVE ostatnio zaktualizowano 14 września, a wpis NVD 18 września, oba nadal na poziomie 9,8.
Dwie kolejne luki zasługują na nazwanie, a nie wygładzanie. Biuletyny doradcze projektu na GitHubie, opublikowane 23 września 2026 r. i wskazujące badacza z JFrog jako zgłaszającego, nadal podają 9,8 dla luki w MCP i 8,1 dla luki w pluginie, bez śladu rewizji opisanej przez Maxima. A zakresy podatności w tych biuletynach są opisane względem wersji modułów Go — poniżej 1.5.27 i poniżej 1.6.3 — a nie względem tagów wydań transports używanych w biuletynach JFrog, więc operator zestawiający jeden dokument z drugim musi uzgodnić dwa schematy numeracji, zanim zdecyduje, czy dana kompilacja jest objęta podatnością.

Co się zmieniło i co polecono robić operatorom
Chronologia biegnie wstecz od ujawnienia, co jest najmniej intuicyjnym elementem zapisu. Pull request #6757 scalono 2 września 2026 r. transports/v2.1.0 — wydanie, które biuletyn wskazuje jako pierwsze zawierające poprawkę — opublikowano 8 września, sześć dni przed publikacją CVE-2026-90898 14 września. Poprawka wtyczki w projekcie poprzedziła jego własny biuletyn w ten sam sposób: transports/v2.0.0 wydano 26 sierpnia, jedenaście dni przed CVE z 6 września. Operatorzy, którzy śledzą wydania, a nie kanały informacyjne, mieli poprawki, zanim otrzymali ostrzeżenia.
To, co daje aktualizacja, jest wąskie i konkretne. W wersji 2.1.0 i późniejszych nieuwierzytelniona rejestracja stdio zwraca 403 i polecenie nie zostaje uruchomione; uwierzytelnieni administratorzy zachowują tę możliwość, a udostępnianie przez config.json nadal działa. Doraźnym rozwiązaniem z biuletynu dla każdego, kto nie może dokonać migracji, jest ustawienie governance.auth_config.is_enabled na true, użycie silnych danych uwierzytelniających administratora i trzymanie listenera zarządzania poza niezaufanymi sieciami. Instrukcja JFrog dla instancji, które były uruchomione w sposób wystawiony na dostęp przy wyłączonym uwierzytelnianiu, nie polega na prowadzeniu dochodzenia i liczeniu na szczęście: należy traktować je jako przejęte oraz wymienić klucze wirtualne i dane uwierzytelniające dostawców.
Arytmetyka wersji to część najbardziej narażona na błędną interpretację. v2.0.0 nie naprawia tej wady. Linia 1.6.x aż do 1.6.11 również nie zawiera poprawki, a najnowszy tag serii 1.6 w projekcie to transports/v1.6.11, opublikowany 14 sierpnia 2026 r.; na dzień 28 października 2026 r. w repozytorium nie ma linii 1.7 — w tej serii nie ma więc wydania z poprawką, a operator 1.6.x musi przejść na 2.1.0 lub nowszą wersję, zamiast czekać na backport. Bieżąca linia wydań znacznie wykracza poza ten punkt: transports/v2.3.2 opublikowano 20 października 2026 r.

{{1}}Po publikacji wydarzyły się dwie rzeczy, z których obrońca może skorzystać.{{/1}} {{2}}Poradniki bezpieczeństwa projektu na GitHubie — GHSA-86gf-xh3g-rvxq dotyczący luki w MCP o wadze krytycznej i GHSA-2qp8-4xgm-fw6g dotyczący luki we wtyczce o wadze wysokiej — pojawiły się 23 września 2026 r., dając kanałom zależności i biuletynów drugi identyfikator do dopasowania.{{/2}} {{3}}A 13 października 2026 r. szablon wykrywania dla CVE-2026-90898 został włączony do publicznego repozytorium nuclei-templates, co oznacza, że sprawdzenie próby nieuwierzytelnionej rejestracji jest teraz czymś, co może uruchomić potok skanowania, a nie czymś, co każdy zespół musi napisać samodzielnie.{{/3}}

Otwarta pozostaje kwestia wagi i zostanie ona rozstrzygnięta lub nie przez dwie organizacje, które wciąż o tym rozmawiają. Stanowisko Maxima, jak podano, jest takie, że 9.8 zawyża ocenę luki, która ma znaczenie tylko wtedy, gdy występuje wystawiony listener i nieustawiona wartość domyślna — twierdzenie, które da się w zasadzie przetestować, ale nie zostało publicznie przetestowane, ponieważ nikt nie opublikował, ile wdrożeń spełniło te dwa warunki. Stanowisko JFrog to ocena, którą przypisał jako CNA, wciąż widniejąca w rekordzie CVE i w NVD. Dopóki jedna z nich nie opublikuje korekty, interpretacja operacyjna jest taka sama w obu przypadkach: luka jest rzeczywista i została zweryfikowana od początku do końca na opublikowanym obrazie kontenera, poprawka została wydana przed ostrzeżeniem, seria 1.6 nie ma żadnej poprawki, a każdą instancję, która działała z wyłączonym uwierzytelnianiem na osiągalnym listenerze, należy traktować jako incydent związany z poświadczeniami, a nie jako poprawkę do zaplanowania.
