Wygenerowana abstrakcyjna ilustracja na ciemnogranatowym tle: mały bursztynowy sześcian serwera po lewej emituje cienką cyjanową linię kształtów przypominających glify, która przechodzi prosto przez wysoką półprzezroczystą niebieską szklaną membranę i ciągnie się do ciemnego panelu terminala po prawej, gdzie świeci pojedynczy bursztynowy blok kursora. Linia jest nieprzerwana. Nie pojawiają się żadne teksty, ludzie ani logotypy organizacji. Logo OrcaRouter jest nałożone w prawym dolnym rogu.
AI Safety Incidents

Logowanie MCP w OpenCode przekazało adres URL serwera do PowerShell — i nie istnieje żadne CVE, które by to oznaczyło

Autor

Magnus Corvin

Data publikacji

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

W dniu 19 października 2026 r. Pillar Security ujawniła lukę umożliwiającą zdalne wykonanie kodu w OpenCode, otwartoźródłowym agencie kodującym utrzymywanym przez Anomaly: zdalny serwer Model Context Protocol skonfigurowany przez dewelopera mógł uruchomić dowolny kod na maszynie tego dewelopera podczas logowania OAuth MCP, bez żadnego monitu o zgodę. Błąd ograniczał się do Windows i Windows Subsystem for Linux, gdzie OpenCode przekazywał dostarczony przez serwer adres URL logowania do polecenia PowerShell bez jego escapowania. Pillar podaje, że zakres objętych wersji to 1.0.137 do 1.18.32. Anomaly naprawiła go w 1.18.33, opublikowanej w npm 28 września 2026 r., i nie wystąpiła o CVE ani nie opublikowała biuletynu zabezpieczeń — więc nic w typowym kanale informacji o lukach nie powie dotkniętemu zespołowi, że powinien dokonać aktualizacji. Pillar nie zgłosiła żadnych dowodów, że luka kiedykolwiek została wykorzystana w ataku. To jeden z rekordów w archiwum incydentów AI, gdzie każdy wpis zawiera własne źródła, poziom ważności, ocenę pewności i oznaczenie sporności.

Na czym właściwie polegał błąd

Gdy klient MCP łączy się ze zdalnym serwerem, który wymaga autoryzacji, przeprowadza uzgadnianie odnajdywania OAuth. Serwer odpowiada kodem 401 i wyzwaniem wskazującym na swoje dokumenty odnajdywania, a jedno pole w tych dokumentach — authorization_endpoint — informuje klienta, gdzie skierować użytkownika, aby się zalogował. Jest to ciąg o dowolnej formie, a strona podlegająca uwierzytelnieniu to strona, która go wybiera.

W OpenCode 1.18.32 ten ciąg trafił z sieci do powłoki. Pillar prześledził ścieżkę od dokumentu odkrywania serwera, przez MCP SDK, do oauth-provider.ts, mcp/index.ts i browser.ts, kończąc na open, małym pakiecie, którego OpenCode używa do uruchamiania przeglądarki. Nic na tej ścieżce nie sprawdzało schematu URL-a i nic nie porównywało go z originem serwera skonfigurowanego przez dewelopera. Uścisk dłoni jest z założenia automatyczny — cały sens polega na wysłaniu cię na stronę logowania bez konieczności kopiowania URL-a — więc między odpowiedzią serwera a programem uruchamiającym nie stał żaden krok zatwierdzania.

The launcher is where it broke. On macOS and Linux, open passes the address as an argument vector and no shell is involved. On Windows, version 10.1.2 of open — the version every affected OpenCode release pinned — builds a PowerShell command, base64-encodes it and runs it with powershell -EncodedCommand. Pillar quotes the source: the application name is escaped on one line, and the target URL is not. PowerShell evaluates $(...) subexpressions inside double-quoted strings, so an address of the form https://evil.test/$([IO.File]::WriteAllText('C:\Users\Public\pwned.txt','RCE')) runs before the browser launch fails. OpenCode discards that failure.

Dwie właściwości sprawiały, że łatwo było to przeoczyć. Ładunek nie zawiera spacji, więc normalizacja URL pozostawia go bez zmian, a jest to składniowo zwykły https adres. A serwer nie musiał być wrogi w momencie konfiguracji: Pillar zauważa, że późniejsza kompromitacja, przejęty wpis rejestru, typosquat lub wygasła domena każdy zamieniłby zaufany wpis konfiguracyjny w mechanizm dostarczania.

Kto został ujawniony?

Narażona populacja to użytkownicy Windows i WSL uruchamiający OpenCode ze skonfigurowanym zdalnym serwerem MCP. Pillar opisuje OpenCode jako mający około 3 miliony tygodniowych pobrań npm i 211 000 gwiazdek GitHub; raport Infosecurity Magazine podaje liczbę gwiazdek na ponad 218 000. Żadna z tych liczb nie jest liczbą instalacji, których dotyczy problem, i nikt takiej liczby nie opublikował.

Punkt wyzwalający to jedyne miejsce, w którym oba główne źródła się rozchodzą, i ma to znaczenie zarówno dla ryzyka, jak i dla wagi problemu. Pillar opisuje wykorzystanie jako niewymagające dodatkowej interakcji ani zgody użytkownika. The Hacker News w swoim raporcie z 22 października podaje, że krok w przeglądarce uruchamia się tylko wtedy, gdy deweloper rozpocznie logowanie — przez uruchomienie opencode mcp auth lub wykonanie odpowiedniego żądania — i że samo skonfigurowanie serwera albo otwarcie sesji do tego nie prowadzi. Tak czy inaczej deweloper nie robi nic nietypowego; rozpoczęcie uwierzytelniania wobec serwera już obecnego w konfiguracji jest rutynowe. Ale „brak interakcji” i „jedna rutynowa interakcja” to różne twierdzenia, a ta różnica bezpośrednio przekłada się na ocenę.

Poprawka nadeszła opisana jako refaktoryzacja.

Pillar zgłosił błąd prywatnie za pośrednictwem GitHub Security Advisory 29 sierpnia 2026, wraz z pełnym materiałem do reprodukcji. 25 września ponowił kontakt poza wątkiem advisory; Anomaly potwierdził, że zgłoszenie dotarło do jego zespołu, i odpowiedział, że złośliwe serwery MCP wykraczają poza jego model zagrożeń. Tego samego dnia pojawił się pull request #51414 — scalony jako commit 29f07e0c. Opisuje się go jako konsolidację ośmiu miejsc wywołań uruchamiania przeglądarki w jeden helper. Wersja 1.18.33 trafiła do npm trzy dni później, 28 września.

Poprawka ma trzy warstwy. Zależność open została przeniesiona do wersji 11.0.4, która otacza cel pojedynczymi cudzysłowami, a PowerShell nie rozwija niczego wewnątrz pojedynczych cudzysłowów. Nowa funkcja pomocnicza openUrl() odrzuca schematy inne niż HTTP(S). Sprawdzenie schematu trafiło do samej funkcji redirectToAuthorization, na granicy, którą Pillar wskazał w swoim raporcie. Ani pull request, ani informacje o wydaniu nie wspominają o luce bezpieczeństwa, a Anomaly nie poprosiło o CVE.

The Hacker News donosi, że opublikowana polityka bezpieczeństwa Anomaly stwierdza, iż serwery MCP konfigurowane przez użytkownika znajdują się „poza naszą granicą zaufania”, a firma wydała ostrzeżenia dotyczące innych luk umożliwiających wykonanie kodu w OpenCode w tym roku, w tym jednej naprawionej w sierpniu. Relacja Pillar dotycząca otrzymanej odpowiedzi jest bardziej dosadna: „zaktualizowaliśmy zależność, ale ogólnie rzecz biorąc, próba poradzenia sobie ze złośliwym serwerem MCP wykracza poza nasz model zagrożeń”.

An HTML timeline card titled 'How a five-year-old escaping bug reached OpenCode', subtitled 'Dated entries from Pillar Security's report and the open package's own issue history', listing nine rows: 22 October 2020, open issue #202 reports that a URL containing a dollar sign breaks on WSL 2; 18 October 2023, issue #323 titles 'OS command injection on windows when opening urls'; 9 July 2025, CVE-2025-6514 in mcp-remote, same sink, CVSS 9.6; 15 November 2025, open 11.0.0 quotes the PowerShell target; 7 December 2025, OpenCode calls open() with a server-supplied URL; 29 August 2026, Pillar reports privately via GitHub Security Advisory; 25 September 2026, pull request #51414 merged; 28 September 2026, OpenCode 1.18.33 published to npm, no CVE and no advisory; 19 October 2026, Pillar publishes. A footer cites Pillar Security and the open repository.

Czytana jako sekwencja, os czasu umieszcza błąd OpenCode na końcu pięcioletniego ciągu, a nie na jego początku. Defekt, który go spowodował, był już publicznie znany, a jego poprawka została już wydana, zanim napisano linię, która go używała.

Dlaczego walidacja schematu by temu nie zapobiegła

Uzgodnionym rozwiązaniem dla tej klasy błędów jest walidacja schematu URL: blokować nietypowe schematy, dopuszczać http i https, koniec. To właśnie dostarcza MCP TypeScript SDK i to właśnie OpenCode dodał w wersji 1.18.33. Ładunek Pillar przechodzi wszystkie te kontrole, ponieważ jest to https. Lista blokowanych w SDK obejmuje javascript:, data: i vbscript:; ostrzejsza lista dozwolonych http/https została zaproponowana w pull requeście SDK #841 w sierpniu 2025 i zamknięta bez scalenia, podczas gdy pull request #877 dostarczył listę blokowanych trzech schematów w v1.17.4 — a Pillar twierdzi, że była to nadal obowiązująca polityka w SDK 1.32.0 w chwili publikacji. To, co faktycznie załatało dziurę w OpenCode, to aktualizacja zależności, a nie kontrole, które wyglądają na poprawkę bezpieczeństwa.

Historia przemawia przeciwko traktowaniu tego jako wpadki jednego projektu. Pakiet open od 2021 r. zawiera w README ostrzeżenie, że nie daje żadnych gwarancji bezpieczeństwa, a oczyszczanie danych wejściowych należy do wywołującego. W październiku 2020 r. użytkownik złożył zgłoszenie #202, informując, że adres URL zawierający znak dolara tracił fragment na WSL 2 — rozwinięcie ciągu, zgłoszone jako irytujący problem z niedziałającym linkiem. W październiku 2023 r. inżynier Adobe złożył zgłoszenie #323 „Wstrzyknięcie polecenia systemowego w systemie Windows podczas otwierania adresów URL”, z jednolinijkowym proof of concept: open('https://$(calc.exe)'). Opiekun projektu zacytował README i powiedział, że pull requesty poprawiające escapowanie są mile widziane; zgłoszenie zamknięto jako nieplanowane trzy dni przed tym, jak open 11.0.0 i tak wprowadził escapowanie, 15 listopada 2025 r. OpenCode napisał swoje wywołanie uruchamiania przeglądarki 7 grudnia 2025 r., trzy tygodnie po tym, jak istniała poprawiona wersja open, na podstawie pinu, który był już przestarzały o kilka miesięcy.

W miesiącach przed napisaniem tego wywołania ekosystem MCP odnotował trzy CVE w tym samym ujściu lub tym samym polu: CVE-2025-6514 w mcp-remote (CVSS 9.6, ujawnione przez JFrog 9 lipca 2025), CVE-2025-58062 w openmcp-client i CVE-2025-10619 w sequa-mcp. Dla kontrastu Pillar zestawia to z klientami, którzy nigdy nie budują polecenia powłoki ze zdalnego ciągu: wymienia gemini-cli, Claude Code, github-mcp-server i mcp-gateway Dockera jako przekazujące URL jako wektor argumentów, co sprawia, że pytanie o to, co zawiera ten ciąg, przestaje mieć kluczowe znaczenie.

A generated abstract illustration on a dark navy field: a long cyan ribbon of abstract glyph shapes runs left to right and splits in two at a hollow chrome ring, which the upper branch passes straight through while the lower branch curves downward into a glowing amber terminal rectangle at bottom right. A faint dotted outline of an empty browser window floats in the upper right. No text, people or organisation logos appear. The OrcaRouter logo is composited in the bottom-right corner.

Co jest ustalone, a co nie

Archiwum oceniło ten rekord na poziom pewności A, a relacje, które za nim stoją, się bronią. Infosecurity Magazine opublikował 20 października własny wywiad z Eilonem Cohenem z Pillar; The Hacker News opublikował własną relację 22 października; DKCERT, krajowy CERT Danii, podsumował ustalenia 21 października, powołując się na Infosecurity; a laboratorium badawcze Cloud Security Alliance opublikowało analizę, która dodaje jedno istotne zastrzeżenie podane poniżej. Żaden z tych podmiotów nie jest stroną zgłaszającą, a wszystkie zgadzają się co do mechanizmu, wersji i cichej poprawki. Sama Anomaly nie opublikowała nic na temat tej luki.

Ustalono, oficjalnie:

• Usterka, jej mechanizm i zakres platform. Pillar wskazuje konkretne linie źródłowe, a poprawka jest widoczna w publicznym diffie między 1.18.32 a 1.18.33; dwa niezależne doniesienia prasowe opisują ten sam przepływ danych.

• Zakres objęty problemem, od wersji 1.0.137 do 1.18.32, oraz wydanie z poprawką, 1.18.33, opublikowane 28 września 2026 r.

• To, że nie istnieje żadne CVE ani żaden biuletyn bezpieczeństwa. Można to sprawdzić i jest to kluczowy fakt dla obrońców.

• Że nie zgłoszono żadnego wykorzystania. Pillar twierdzi, że nie zaobserwował oznak wykorzystania w atakach, a The Hacker News zauważa, że nie opublikowano żadnych wskaźników kompromitacji. Brak opublikowanych wskaźników nie jest dowodem na ich brak, a bez telemetrii od dostawcy nie można potwierdzić żadnej z tych interpretacji.

Nieustalone lub w napięciu:

• 9.8. Liczba ta to proponowana przez Pillar ocena CVSS v3.1, a nie oficjalna: bez CVE nie ma oceny NVD ani oceny dostawcy. Nota badawcza Cloud Security Alliance wskazuje, że 9.8 zakłada brak interakcji użytkownika, a jeśli opis wyzwalacza podany przez The Hacker News jest prawidłowy, lepiej pasowałaby ocena wymagająca interakcji użytkownika — około 8.8. Ten tekst tego nie rozstrzyga; własny tag wysokiej wagi archiwum to klasyfikacja, nie ocena.

• Data publikacji. Raport Pillar ma w nagłówku datę 19 października 2026 r. i oba teksty prasowe podają tę datę; oś czasu ujawnień w stopce samego raportu Pillar wskazuje jako datę publikacji 4 października. Archiwum odnotowuje 19 października z dokładnością do dnia.

• Wielkość populacji objętej ekspozycją. Nie opublikowano żadnej liczby. Podane powyżej liczby pobrań i gwiazdek to metryki repozytorium, a nie liczba instalacji.

• Czy jakakolwiek maszyna została faktycznie naruszona. Nic, co opublikowano, tego nie potwierdza, a zapis nie wskazuje na rzeczywistą szkodę.

An HTML card titled 'Established, and not', split into two columns. The left column, headed 'Established', lists: affected versions 1.0.137 to 1.18.32, Windows and WSL only; fixed in 1.18.33 on 28 September 2026; no CVE and no security advisory issued; no exploitation reported and no indicators published. The right column, headed 'Not established', lists: official severity, since 9.8 is Pillar's proposed score with no CVE to attach it to; the publication date, 19 October in the report header and 4 October in its own timeline; the number of exposed installations; whether any host was compromised. A footer cites Pillar Security, The Hacker News and the Cloud Security Alliance research note.

Co się zmieniło i co zrobić

Remediacja polega na sprawdzeniu wersji, ponieważ nic innego ci tego nie powie. OpenCode 1.18.33 lub nowszy jest naprawiony. Dotknięte instalacje trzeba znaleźć, inwentaryzując pakiet bezpośrednio: Pillar zaleca inwentaryzację samego OpenCode zamiast czekania na kanał, a nota Cloud Security Alliance sugeruje odpytywanie o wersję pakietu opencode-ai, ponieważ nie ma identyfikatora, z którym mógłby zostać dopasowany kanał. Zespoły, które nie mogą wykonać aktualizacji i używają Windows lub Windows Subsystem for Linux, powinny usunąć niezweryfikowane zdalne serwery MCP ze swojej konfiguracji OpenCode; opencode mcp list pokazuje, które serwery są obecne.

Dla każdego, kto utrzymuje klienta MCP, wytyczne Pillar są węższe niż zwykłe zalecenia: przekazuj adresy URL jako wektor argumentów i nigdy nie buduj wiersza poleceń ze zdalnego ciągu; wiąż odkrywanie OAuth z originem serwera skonfigurowanego przez użytkownika oraz traktuj dokumenty odkrywania, metadane serwera i deskryptory narzędzi jako niezaufane dane wejściowe, a nie jako ustawienia. Nota Cloud Security Alliance dodaje heurystyki wykrywania — proces OpenCode uruchamiający powershell.exe z -EncodedCommand, przykładowo — podkreślając, że są to sugestie dla inżynierii wykrywania, a nie opublikowane wskaźniki kompromitacji.

To nie jest naruszenie Console

Ujawnienie Pillar miało miejsce kilka dni po tym, jak Anomaly potwierdziła odrębny incydent naruszenia hostowanej konsoli OpenCode, który mógł narazić na szwank przechowywane klucze dostawców API. Oba zdarzenia nie są ze sobą powiązane, a Eilon Cohen z Pillar jasno wskazał tę różnicę w wywiadzie dla Infosecurity Magazine. „Naruszenie dotyczyło starszego systemu za hostowanym proxy kluczy i ujawniło klucze dostawców, które użytkownicy tam przechowywali” — powiedział. „Zgłoszona przez nas podatność działa w drugą stronę: złośliwy zdalny serwer MCP wykonuje kod na komputerze samego dewelopera podczas uzgadniania OAuth. Inny cel i inna pozycja atakującego”. Naruszenie Console to odrębny wpis w archiwum i oba przypadki należy czytać jako osobne pozycje.

Co je łączy, w ujęciu Cohena, to pytanie leżące u podstaw obu: „Komu pozwalasz przekazywać poświadczenia i dane wejściowe narzędziu AI do kodowania i co to narzędzie z nimi robi?”

Luka w ujawnianiu informacji to ta część, która trwa dłużej niż sam błąd. Błąd, który jego znalazcy uznają za krytyczny, naprawiony w ramach podbicia wersji zależności i nieobecny w żadnym z automatycznych sygnałów, na których obrońca zwykle polega, sprawia, że bezpośrednia inwentaryzacja pozostaje jedyną metodą wykrycia — a dostawca nie opublikował żadnego biuletynu, który komukolwiek nakazywałby ją przeprowadzić.