
MaxKB dołączył narzędzie powłoki do każdego asystenta obsługującego narzędzia i nigdy nie ograniczył do niego dostępu
- OrcaNOWOŚĆOrcaCyber: GLM 5.3 Flash Abliterated2026-10-2796 tok/s
- OrcaNOWOŚĆOrcaCyber: Qwen3.8 Flash Next Abliterated2026-10-26$0.80 / $1.60 za 1 mln tokenów · 252 tok/s
- OrcaNOWOŚĆOrcaCyber: MiMo V2.6 Flash Abliterated2026-10-26$0.80 / $1.60 za 1 mln tokenów · 89 tok/s
- MoonshotNOWOŚĆMoonshotAI: Kimi K3.1 Pro2026-10-2446Inteligencja
- OrcaNOWOŚĆOrcaCyber: DeepSeek V4.1 Flash Abliterated2026-10-23$0.80 / $1.60 za 1 mln tokenów · 107 tok/s
- minimaxNOWOŚĆMiniMax: M3.1 Flash2026-10-1929Inteligencja
- OrcaNOWOŚĆOrca: OrcaCyber Ultra 1.02026-10-17$5.00 / $10.00 za 1 mln tokenów · 53 tok/s
- deepseekNOWOŚĆDeepSeek: DeepSeek V4.1 Flash 10172026-10-1733Inteligencja
- DeepSeekNOWOŚĆDeepSeek: DeepSeek V4.1 Flash2026-10-1740Inteligencja
- OrcaOrca: OrcaCyber Zero 1.52026-10-10$3.00 / $7.50 za 1 mln tokenów · 116 tok/s
- openaiOpenAI: GPT-6.1 Sol2026-09-2955Inteligencja
- anthropicAnthropic: Claude Sonnet 5.52026-09-2854Inteligencja
- typesafeTypeSafe: Jev 1.132026-09-24$0.04 / $0.00 za 1 mln tokenów · 140 tok/s
- OpenAIOpenAI: GPT-6 Luna2026-09-2228Inteligencja
- OpenAIOpenAI: GPT-6 Sol2026-09-2248Inteligencja
- AnthropicAnthropic: Claude Opus 5.52026-09-2258Inteligencja
- xiaomiXiaomi: MiMo-V2.6-Flash2026-09-2127Inteligencja
- xiaomiXiaomi: MiMo-V2.6-Pro2026-09-2130Inteligencja
- xAIGrok 4.72026-09-2134Inteligencja
- OrcaOrca: OrcaCyber Zero 1.02026-09-17$3.00 / $7.50 za 1 mln tokenów · 182 tok/s
MaxKB, open-source'owa platforma asystenta przedsiębiorstwa publikowana w organizacji GitHub 1Panel-dev, zbudowała swoich agentów czatu na frameworku, który po cichu dodaje narzędzie powłoki, gdy tylko przekazany zostanie backend obsługujący powłokę — a MaxKB nigdy nie usunął tego narzędzia ani nie poprosił nikogo o zatwierdzenie jego użycia. Wada to CVE-2026-77521, opublikowana jako biuletyn GitHub GHSA-f36j-f34j-h3rx 2 września 2026 r. i oceniona na 10,0 na 10 w CVSS 3.1 w przypadku publicznego lub wbudowanego asystenta. Lasso Security, które ją znalazło i zgłosiło, wykazało, że wiadomość czatu — lub tekst, który asystent jedynie przyswaja poprzez wyszukiwanie albo przesłany dokument — może skłonić model do uruchomienia poleceń: w przypadku wdrożenia na gołym metalu bezpośrednio na hoście, a w przypadku oficjalnego kontenera poprzez wrapper, który według badaczy można obejść średnikiem. Żadne z cytowanych źródeł nie odnotowuje wykorzystania tej wady w rzeczywistych atakach. Własna ocena dotkliwości, ocena pewności i lista źródeł tego rekordu znajdują się w archiwum incydentów AI, obok sąsiednich wpisów dotyczących MaxKB i narzędzi agentowych z tej samej partii ujawnień.
MaxKB to produkt do samodzielnego hostowania służący do budowania asystentów opartych na wyszukiwaniu: operator tworzy asystenta, przypisuje mu możliwości — narzędzia, serwery Model Context Protocol, umiejętności, podaplikacje — podłącza bazę wiedzy zbudowaną z przesłanych dokumentów lub zindeksowanych stron internetowych, a następnie udostępnia asystenta albo przez uwierzytelnioną konsolę, albo jako publiczny, osadzany widget czatu. Ta wszechstronność jest źródłem ekspozycji. Warunek wyzwalający z biuletynu bezpieczeństwa nie jest nietypową konfiguracją, lecz zwyczajną: każdy asystent z co najmniej jedną przypisaną możliwością kieruje swój czat przez dotkniętą ścieżkę agenta, natomiast czat bez przypisanych możliwości tego nie robi. W opracowaniu Lasso projekt opisano jako jeden z szerzej przyjętych w swojej kategorii i zauważono, że MaxKB jest zwykle wdrażany jako usługa wielodostępna — co sytuuje polecenie uruchamiane jako użytkownik aplikacji pod modelem dzierżawy, a nie w obrębie wycinka należącego do jednego dzierżawcy.
Narzędzie powłoki pojawiło się wraz z frameworkiem, a nie z produktem
MaxKB buduje tych agentów za pomocą biblioteki deepagents firmy LangChain, przypiętej do wersji 0.6.11 w pliku pyproject.toml projektu zarówno w tagu podatnym, jak i w bieżącym. W apps/application/flow/tools.py, w wierszu 467 tagu v2.10.3-lts, projekt wywołuje create_deep_agent z backendem ustawionym na SandboxShellBackend, podklasę MaxKB, która uruchamia polecenia na hoście. Zgodnie z biuletynem doradczym deepagents automatycznie wstrzykuje zestaw narzędzi, gdy w ten sposób zostanie przekazany backend powłoki: execute, ls, read_file, write_file, edit_file, glob i grep. Nie są one częścią argumentu tools=list, który zawiera wyłącznie narzędzia samego operatora, narzędzia MCP i narzędzia umiejętności. Nie można ich usunąć z interfejsu ani poprzez konfigurację.
MaxKB również nie przekazuje excluded_tools, argumentu bibliotecznego, który by je usuwał. Komunikat doradczy starannie wyjaśnia, dlaczego ma to znaczenie nawet jako środek zaradczy: excluded_tools „usuwa narzędzie z informacji przekazywanych modelowi, a nie z executora”. Rozróżnienie między narzędziem, którego model nie zna, a narzędziem, którego nie można uruchomić, to cały ten błąd w pigułce.
Bramka, która wymienia trzy narzędzia i pomija czwarte.
Mechanizm human-in-the-loop w tym samym wywołaniu to jedna linia i wylicza trzy operacje: interrupt_on={"write_file": False, "read_file": False, "edit_file": False}. Zapis pliku, odczyt pliku i edycja pliku są nazwane. Wykonywanie poleceń w ogóle nie jest kluczem w słowniku. W interpretacji biuletynu doradczego oznacza to, że nie jest wymagane zatwierdzenie dla execute — trzy operacje systemu plików są nazwane i jawnie ustawione tak, aby nie powodować przerwania, a narzędzie powłoki nie jest w ogóle nazwane.
Poskładane razem, ścieżka wygląda tak: niezaufany tekst dociera do modelu, model wywołuje execute, a polecenie zostaje uruchomione. Komunikat wskazuje dwa sposoby, w jakie może dotrzeć niezaufany tekst. Bezpośredni to czat — publiczny lub osadzony widget albo rozmowa innego dzierżawcy. Pośredni to treść, którą przyswaja asystent: dokument RAG, przesłany plik albo strona internetowa, którą platforma indeksuje do bazy wiedzy. Wpis Lasso ukonkretnia drugą drogę, zauważając, że „zbiór osób, które mogą umieścić tekst przed modelem, jest większy niż zbiór osób, które mogą z nim rozmawiać”.
W instalacji bare-metal polecenie jest po prostu poleceniem.
To, co MaxKB robi w zakresie izolacji, rozgrywa się w apps/application/flow/backend/sandbox_shell.py, a w wersji v2.10.3-lts zaczyna się od wartości domyślnej. W wierszu 9 znajduje się _enable_sandbox = bool(int(CONFIG.get("SANDBOX", 0))), a SANDBOX nie występuje w Config.defaults w apps/maxkb/conf.py. Wobec braku jawnego ustawienia MAXKB_SANDBOX wartość wynosi zero, gałąź wrappera w wierszu 65 jest pomijana, a execute dociera do subprocess.run z shell=True bezpośrednio na hoście, jako użytkownik uruchamiający usługę — root, zgodnie z sformułowaniem z komunikatu doradczego, jeśli usługa działa jako root.
To jest konfiguracja, której badacze użyli do swojego proof of concept na hoście. Uruchomili prawdziwy kod MaxKB ze źródeł z nieustawioną zmienną MAXKB_SANDBOX, utworzyli asystenta z jednym podłączonym narzędziem i poprosili go w jednej wiadomości czatu o uruchomienie poleceń informujących o systemie. Narzędzie execute zadziałało i zapisało plik, którego zawartością były wyniki uname, id i sw_vers samego hosta — wyniki, co odnotowuje biuletyn, potwierdzono jako nieobecne w żadnym kontenerze. Lasso odnotowuje również granicę tego, co to powstrzymało: model odmówił obsługi pliku dowodowego o oczywistej nazwie, ale nieszkodliwe sformułowanie operacyjne nie zostało odrzucone. Dopasowanie modelu, ich słowami, jest „częściowym spowalniaczem, a nie mechanizmem kontrolnym”.
Na oficjalnym obrazie sandbox działał, a mimo to doszło do wycieku.
Oficjalny kontener ustawia MAXKB_SANDBOX=1 w obrazie bazowym, w pliku installer/Dockerfile-base w wierszu 48, więc wrapper jest tam aktywny — a wrapper to druga wada. Budował jeden ciąg: env -i LD_PRELOAD=/opt/maxkb-app/sandbox/lib/sandbox.so, po którym następowało gosu sandbox, a potem polecenie dostarczone przez model, przekazywany do powłoki działającej jako root. Ponieważ polecenie było interpolowane jako tekst, tylko jego pierwszy token znajdował się pod gosu. Każdy średnik, potok, przekierowanie lub podstawienie polecenia w danych wyjściowych modelu był oceniany przez zewnętrzną powłokę roota, zanim sandbox w ogóle go zobaczył.
Opis Lasso przedstawia działający schemat tego: ładunek env -i LD_PRELOAD=... PATH="$PATH" gosu sandbox ls; whoami; id, w którym ls jest ograniczone, whoami nie, a wszystko po nim działa bez ograniczeń. W testach badacze zapisali plik należący do roota za pomocą przekierowania, podczas gdy wewnętrzne polecenie w piaskownicy zostało zablokowane. Co pogarsza sprawę, ani installer/Dockerfile, ani installer/Dockerfile-base nie zawiera dyrektywy USER, więc obraz aplikacji działa jako UID 0 — biuletyn bezpieczeństwa potwierdza uzyskanie uprawnień roota w czasie działania. Kontener mimo to wykonywał polecenia, a piaskownica decydowała jedynie, które z nich były kosmetycznie przypisane użytkownikowi o niskich uprawnieniach.
Pełny opisany przez Lasso przebieg ataku wcale nie wymaga dostępu do celu. Atakujący umieszcza polecenia na stronie internetowej, czeka, aż agent ofiary zindeksuje ją w bazie wiedzy, a następnie ofiara zadaje zwykłe pytanie. Odpowiedź wraca poprawna i wiarygodna; wstrzyknięty curl został już uruchomiony na serwerze atakującego. W biuletynie doradczym zauważono, że badacze testowali wyłącznie własne wdrożenia, a nie żadną zewnętrzną ani hostowaną instancję MaxKB.
Co wynika ze źródeł, a czego po prostu nie zmierzono
Mechanizm, dwa tryby wdrożenia, przypisanie autorstwa i wydanie z poprawką są spójne w czterech dokumentach: advisory GitHub, rekordzie NVD opublikowanym 21 września 2026 r., własnym opracowaniu technicznym Lasso z 10 września 2026 r. oraz raporcie GBHackers z 22 września 2026 r., który jest jedynym niezależnym materiałem medialnym znalezionym dla tego CVE. Żadne źródło nie kwestionuje żadnej części tego ustalenia, a archiwum odnotowuje ten wpis jako niekwestionowany na najwyższym poziomie pewności.
To, czego źródła nie zawierają, to jakakolwiek miara ekspozycji. Nie ma liczby wdrożeń MaxKB, liczby asystentów dostępnych z internetu ani osadzonych, wyniku skanowania, telemetrii ani wskazanego poszkodowanego. Nic w materiale nie pokazuje, że luka została wykorzystana przeciwko komukolwiek, i ocena wykorzystania samej CISA się z tym zgadza: blok SSVC dołączony do rekordu NVD w dniu 22 września 2026 r. ocenia wykorzystanie jako „poc”, automatyzowalność jako „yes”, a wpływ techniczny jako „total”. Model EPSS FIRST oszacował prawdopodobieństwo wykorzystania w ciągu najbliższych 30 dni na 1,05 proc., co odpowiada 64. percentylowi, na dzień 27 października 2026 r., a CVE nie występuje w katalogu CISA Known Exploited Vulnerabilities z datą 27 października 2026 r. Sama ocena archiwum odzwierciedla te same dowody: waga wysoka, rzeczywista szkoda fałszywa.
Wartość 10.0 zasługuje na wyraźne określenie swojego zakresu, ponieważ jest to liczba najczęściej cytowana bez kontekstu. To ocena dla przypadku publicznego lub osadzonego asystenta, w którym wektor CVSS ma postać AV:N/AC:L/PR:N/UI:N/S:C — osiągalność sieciowa, brak uprawnień, brak interakcji użytkownika, ze zmianą zakresu, ponieważ polecenie wewnątrz asystenta przechodzi do systemu operacyjnego hosta. Ocena należy do CNA, a CNA jest tutaj program doradczy GitHuba, na który wskazuje również identyfikator źródła rekordu CVE. NVD podaje ten sam wektor jako metrykę dodatkową i na dzień 28 października 2026 r. wymienia wpis ze statusem „Deferred”, co oznacza, że NVD opublikowało analizę podmiotu przypisującego, a nie własną.

Poprawka została udostępniona miesiąc przed publikacją biuletynu bezpieczeństwa.
Chronologia biegnie wstecz od publikacji i jest najmniej intuicyjną częścią zapisu. Lasso zgłosił tę wadę prywatnie za pośrednictwem kanału doradczego GitHuba 8 lipca 2026 r. MaxKB odpowiedział następnego dnia, zawężając zgłoszenie do oficjalnego obrazu i prosząc o dowód koncepcji w kontenerze; badacze dostarczyli go wraz z obejściem piaskownicy 10 lipca. Poprawka w commicie 594f50f2 trafiła 9 lipca — dzień po zgłoszeniu — i przepisała sandbox_shell.py tak, aby ciąg poleceń modelu był najpierw analizowany, a prefiks gosu stosowano do każdego prostego polecenia, a nie tylko do pierwszego, przy czym każda lista argumentów jest ponownie ujmowana w cudzysłowy, aby podstawienie nie mogło przedostać się do powłoki nadrzędnej. W opisie Lasso zmiana ta jest przedstawiona jako stosowanie prefiksu gosu „do każdego prostego polecenia, nie tylko do pierwszego”.
Wydanie zawierające tę poprawkę, v2.10.5-lts, opublikowano 6 sierpnia 2026 r. Biuletyn GitHub pojawił się 2 września, NVD opublikowało CVE 21 września, dodano blok SSVC CISA, a GBHackers poinformowało o tym 22 września, natomiast własne opracowanie Lasso ukazało się 10 września — w środku tej sekwencji, a nie na jej początku. Operator śledzący tagi wydań, a nie kanały biuletynów, miał łatkę około cztery tygodnie przed ostrzeżeniem.
Granica wersji zasługuje na więcej uwagi, niż poświęca jej biuletyn, ponieważ dwa główne źródła są ze sobą sprzeczne, a kwestię rozstrzyga repozytorium. Pole formularza biuletynu podaje wersje objęte problemem jako „<= 2.10.3-lts", wraz z uwagą, że zweryfikowano to na wersji 2.10.3-lts oraz że podatna ścieżka „prawdopodobnie" dotyczy wszystkich wersji, które budują agentów w ten sposób. Własny opis Lasso podaje zakres objętych wersji jako „<= 2.10.4-lts". Tagi potwierdzają szerszy zakres: v2.10.4-lts, wydana 16 lipca 2026 r., zawiera ten sam 75-wierszowy plik sandbox_shell.py co v2.10.3-lts, a przepisany 311-wierszowy plik po raz pierwszy pojawia się w v2.10.5-lts. Operator korzystający z wersji 2.10.4-lts, który przeczytałby wyłącznie zakres podany w biuletynie, doszedłby do wniosku, że znajduje się poza nim. Nie znajdował się.

Czego poprawka nie zrobiła
To, co naprawia 2.10.5-lts, to wrapper: nie buduje już pojedynczego ciągu powłoki z uprawnieniami roota. Nie robi natomiast niczego w kwestii narzędzia. Bezpośrednia lektura repozytorium na tagu v2.10.8-lts, opublikowanym 22 października 2026, pokazuje, że agent jest nadal konstruowany z backend=SandboxShellBackend, a interrupt_on nadal zawiera dokładnie trzy klucze — write_file, read_file i edit_file — bez execute. Pierwsze dwie sugestie naprawcze z biuletynu bezpieczeństwa — domyślne oparcie na backendzie niewykonującym oraz dodanie "execute": True do mapy zatwierdzeń — nie występują w tym wydaniu.
Zalecenie fail-closed pojawiło się później, w wersji v2.10.7-lts, i ma znaczenie dla trybu wdrożenia, który był w najgorszej sytuacji. Wydana 15 października 2026 r. wersja zmienia wiersz w sandbox_shell.py z CONFIG.get("SANDBOX", 0) na CONFIG.get("SANDBOX", 1). Instalacja ze źródeł lub typu bare-metal, w której nigdy nie ustawiono tej zmiennej, ma teraz domyślnie włączony wrapper zamiast wyłączonego, co w wąskim sensie jest zaleceniem „fail closed on non-container deploys”. Dokument doradczy pod tym samym nagłówkiem wymagał jednak więcej — aby przepływ z możliwością wykonywania odmawiał uruchomienia, gdy środowisko uruchomieniowe sandboxa jest niedostępne — a osobno wymagał, aby wrapper nigdy nie budował ciągu poleceń dla powłoki roota. Po stronie kontenerów, co jest faktem, a nie zaleceniem: ani installer/Dockerfile, ani installer/Dockerfile-base nie zawierają dyrektywy USER w tagu v2.10.8-lts, więc obraz aplikacji nadal uruchamia się jako root.
Czytane łącznie, stan odnotowany na dzień 28 października 2026 r. przedstawia się następująco. Druga połowa luki — piaskownica, z której wydostał się średnik — została zamknięta, podobnie jak domyślne zachowanie fail-open we wdrożeniach na hoście. Pierwsza połowa — narzędzie execute, które przychodzi z obiektem backendu i nie jest kluczem w mapie zatwierdzeń — wciąż jest sposobem, w jaki MaxKB buduje asystenta z obsługą narzędzi. Własne zalecenie naprawcze badaczy było wąskie: zaktualizować do wersji 2.10.5-lts lub nowszej i uruchomić wersję Docker z włączoną piaskownicą. GBHackers przekazało tę samą instrukcję oraz szerszą listę dla administratorów — wyłączyć backendy agentów obsługujące powłokę, chyba że wykonanie kodu jest wyraźnie wymagane; wymagać zatwierdzenia przez człowieka przed każdą akcją execute; uruchamiać kontenery jako użytkownik inny niż root; oraz traktować strony pobrane przez crawler, dokumenty RAG i przesłane pliki jako niezaufane dane wejściowe.
Drugi rekord MaxKB z tej samej wrześniowej partii
Drugi wpis MaxKB w archiwum z tej partii to inna usterka z gorszym zakończeniem. CVE-2026-77516, również opublikowany w NVD 21 września 2026 r., to obejście uprawnień, a nie wstrzyknięcie poleceń: od wersji 2.0.0 do 2.9.2 członek przestrzeni roboczej o najniższej roli, któremu jawnie odmówiono dostępu do narzędzia przez WorkspaceUserResourcePermission, nadal mógł powiązać identyfikator tego narzędzia przez tool_ids, skill_tool_ids lub mcp_tool_ids i wykonać je przez ścieżkę dyspozycji agenta lub przepływu pracy. Ścieżka dyspozycji nie stosuje ponownie uprawnienia do poszczególnych narzędzi, którego egzekwują dedykowane trasy narzędzi, a wykonanie narzędzia odszyfrowuje init_params po stronie serwera, więc wywołujący otrzymuje poświadczenia przenoszone przez narzędzie, do którego odmówiono mu dostępu. Jego ocena wynosi 5.4, a opis NVD kończy się zdaniem, którego CVE-2026-77521 nie musi zawierać: „Na dzień tej analizy nie jest dostępna żadna poprawiona wersja”.
Kontrast jest użyteczny dla każdego, kto ocenia tę parę. Podatność, która uzyskała ocenę 10.0, miała poprawkę wprowadzoną w ciągu jednego dnia i wydaną miesiąc przed jej publikacją. Podatność, która uzyskała ocenę 5.4, nie miała opublikowanej poprawionej wersji w momencie publikacji jej CVE.

To, co pozostaje naprawdę otwarte, jest mniejsze, niż sugeruje ocena, i większe, niż wynika z notatki o łatce. Odkrycie nie jest kwestionowane, a mechanizm został zweryfikowany od początku do końca w obu trybach wdrożenia przez zespół, który go odkrył. Ekspozycja jest całkowicie niezmierzona — nikt nie opublikował, ile asystentów MaxKB ma narzędzie, ile z nich jest osiągalnych dla niezaufanej strony ani ile działa na hoście bez piaskownicy — więc rzeczywiste skutki tej wady są funkcją nawyków wdrożeniowych, których nie liczy żadne z cytowanych źródeł. A ta część projektu, która doprowadziła ocenę do maksimum, nadal występuje w bieżącym wydaniu: funkcja uruchamiania poleceń, domyślnie dołączona, nieobecna w mapie, która najpierw pyta człowieka.
