Dziewięć luk w MCP w jeden miesiąc. Żadna nie jest nowa
Od 2 października do 2 listopada opublikowano dziewięć podatności w oprogramowaniu MCP. Wszystkie mają nazwy znane od dwudziestu lat: SSRF, wstrzyknięcie poleceń, brak uwierzytelnienia, CORS z gwiazdką.
2 listopada wieczorem ktoś wszedł do infrastruktury GitBooka, platformy, na której dokumentację trzyma duża część branży kryptowalut. Firma nazwała to atakiem wysoko celowanym, przeprowadzonym z użyciem agentów AI. W zaleceniach dla klientów, obok wymiany tokenów API i sekretów integracji, znalazł się punkt, który jeszcze rok temu nie miałby sensu: każdy, kto korzysta z serwera MCP GitBooka, musi zalogować się ponownie.
Nie wiemy, czy serwer MCP odegrał w tym włamaniu jakąkolwiek rolę. GitBook nie wyjaśnił, jak napastnik użył agentów ani skąd miał dane dostępowe, i nie należy tej luki zapełniać domysłami. Wiemy za to coś innego: serwer MCP trafił na listę rzeczy, które trzeba unieważnić po incydencie. Stoi już w tym samym szeregu co klucze API.
Tego samego dnia opublikowano dziewiątą w ciągu miesiąca podatność w oprogramowaniu MCP. Zestawiliśmy wszystkie dziewięć i jedna rzecz rzuca się w oczy od razu: żadna z nich nie jest nowa.
Dziewięć luk, jeden miesiąc
Lista obejmuje okres od 2 października do 2 listopada 2026. Ujęliśmy w niej błędy, w których serwer MCP, jego konfiguracja albo platforma nim zarządzająca jest drogą ataku. Ostatnia kolumna mówi, jak tę klasę błędu nazywano, zanim pojawili się agenci.
| Data | Produkt | Co się działo | CVSS | Poprawka | Stara nazwa |
|---|---|---|---|---|---|
| 2.10 | mcp-server-fetch (serwer referencyjny) | narzędzie fetch pobiera dowolny adres, także wewnętrzny | 7,3 | w dniu publikacji poprawka czekała na akceptację | SSRF |
| 2.10 | Loom for AWS | bez skonfigurowanego dostawcy tożsamości każdy klient sieci dostaje uprawnienia superadministratora, łącznie z rejestrowaniem serwerów narzędzi i odczytem poświadczeń | 10,0 | 1.6.1 | uwierzytelnianie otwarte przy braku konfiguracji |
| 5.10 | Langflow | pole command z konfiguracji serwera MCP uruchamiane przez bash -c bez listy dozwolonych poleceń | 9,9 | 1.10.3 | wstrzyknięcie poleceń |
| 9.10 | x64dbg-MCP Server | wszystkie narzędzia debugera dostępne przez HTTP bez uwierzytelnienia, nasłuch na 0.0.0.0 | 9,3 | 1.1 | brak uwierzytelnienia |
| 13.10 | Visual Studio i SSMS (Copilot) | agent zapisuje .mcp.json. z kropką na końcu, omija ochronę pliku i rejestruje własny serwer MCP | 8,8 | VS 17.14.42 i 18.10.4 | normalizacja ścieżki |
| 16.10 | Claude Agent SDK (Python) | identyfikator sesji zaczynający się od myślnika staje się flagą --mcp-config i definiuje serwer MCP uruchamiany przy starcie | 9,2 | 0.2.121 | wstrzyknięcie argumentów |
| 19.10 | Google OSS Agent Mesh (SAM) | każdy posiadacz ważnego tokenu OIDC sam zapisuje się do sieci i wywołuje dowolne narzędzia na wszystkich podłączonych serwerach MCP | 9,3 | 0.1.0-alpha.9 | domyślna polityka „wszystko dla wszystkich” |
| 30.10 | MoLing | strona WWW otwarta w przeglądarce ofiary czyta identyfikator sesji i przejmuje narzędzia serwera, także nasłuchującego tylko na localhost | 9,6 | 0.5.0 | CORS z gwiazdką |
| 2.11 | AWS Serverless MCP Server | odczyt, a przy włączonym zapisie także nadpisywanie plików JSON poza katalogiem wdrożenia | 6,1 | 0.2.1 | path traversal |
Wstrzyknięcie poleceń, brak uwierzytelnienia i path traversal były już w pierwszym zestawieniu OWASP Top 10 z 2003 roku. SSRF dostało w nim osobną kategorię w 2021 roku, a zbyt szeroki CORS to błąd tak stary jak sam CORS. Nowe jest tylko miejsce, w którym się pojawiły. Serwer MCP to drzwi, przez które agent wchodzi do systemu, a jego kod bywa pisany jak wtyczka na weekend.
Dziewięć pozycji układa się w trzy wzorce.
Wzorzec pierwszy: konfiguracja jest kodem
Serwer MCP działający przez transport stdio nie ma adresu. Ma polecenie, które klient uruchamia jako proces potomny. Tak wygląda typowy wpis w pliku konfiguracyjnym:
{
"mcpServers": {
"dokumentacja": {
"command": "npx",
"args": ["-y", "@firma/docs-mcp"]
}
}
}
npx -y @firma/docs-mcp z uprawnieniami użytkownika. Kto może zmienić pole command, ten wybiera, co zostanie uruchomione.Dlatego plik konfiguracyjny MCP trzeba traktować jak skrypt wykonywalny, a nie jak ustawienia. Trzy październikowe luki to trzy różne sposoby dopisania czegoś do takiego pliku.
W Langflow wystarczyło dodać serwer w ustawieniach albo zbudować przepływ z komponentem MCP Tools. Polecenie wykonywało się na hoście, gdy tylko Langflow próbował połączyć się z serwerem, nawet jeśli interfejs zgłaszał potem błąd startu. Jeśli włączone było LANGFLOW_AUTO_LOGIN, ustawienie przeznaczone wyłącznie do pracy lokalnej, nie trzeba było się nawet logować. To kolejna odsłona tej samej klasy w tym samym produkcie: poprzednią, CVE-2026-105740, załatano w wersji 1.9.0, a firma Previdian rejestrowała próby jej wykorzystania jeszcze 19 października.
W Visual Studio nie był potrzebny nawet dostęp do ustawień. Copilot miał zakaz zapisu do pliku .mcp.json, ale ochrona porównywała nazwy jako tekst, zanim Windows je znormalizował. Nazwa .mcp.json. różni się od chronionej, a Windows przy tworzeniu pliku usuwa kropkę z końca. Agent, nakłoniony instrukcją ukrytą w treści, którą użytkownik otworzył, mógł więc zarejestrować własny serwer, a IDE go uruchamiało.
W Claude Agent SDK drogą był identyfikator sesji. Aplikacja, która przekazywała do opcji resume wartość od użytkownika, pozwalała podać identyfikator zaczynający się od myślnika. CLI czytało go wtedy jako osobną flagę, więc dało się wstrzyknąć --mcp-config z definicją serwera stdio. Polecenie wykonywało się przy starcie, poza kontrolą uprawnień SDK: allowed_tools i can_use_tool pilnują wywołań narzędzi przez agenta, a nie procesów uruchamianych z konfiguracji.
Ten ostatni przypadek pokazuje sedno wzorca. Uprawnienia agenta są zwykle zdefiniowane na poziomie narzędzi. Konfiguracja MCP leży piętro niżej, więc kto ją kontroluje, omija uprawnienia agenta w całości.
Wzorzec drugi: domyślnie otwarte
Cztery luki z listy nie wymagały żadnej sztuczki, tylko pozostawienia ustawień domyślnych.
- x64dbg-MCP przed wersją 1.1 nasłuchiwał na wszystkich interfejsach i nie pytał o hasło. Każdy klient w sieci mógł podpiąć się do procesów, czytać i zapisywać pamięć oraz tworzyć pliki.
- Loom for AWS zwracał stałą tożsamość superadministratora, gdy nie podłączono Cognito ani zewnętrznego dostawcy tożsamości. Świeża instalacja była więc najbardziej otwartym stanem systemu.
- Agent Mesh publicznie podawał swoją konfigurację OIDC, przyjmował rejestrację od każdego, kto miał ważny token od tego dostawcy, a domyślna polityka dawała uwierzytelnionym dostęp do wszystkich usług. Poprawka w alpha.9 polega na tym, że brak polityki oznacza odmowę.
- MoLing w trybie SSE nie uwierzytelniał żądań, a biblioteka mcp-go wysyłała nagłówek
Access-Control-Allow-Origin: *.
Ostatni przypadek zasługuje na osobny akapit, bo obala popularne przekonanie, że serwer na localhost jest bezpieczny. Do serwera nie łączy się napastnik, tylko przeglądarka ofiary. Wystarczy, że ofiara otworzy stronę napastnika, gdy serwer działa. Strona otwiera połączenie EventSource do /sse i z pierwszego zdarzenia odczytuje identyfikator sesji. Dzięki gwiazdce w nagłówku CORS przeglądarka pozwala na ten odczyt. Z identyfikatorem w ręku napastnik wywołuje narzędzia serwera, a MoLing to serwer do obsługi komputera i przeglądarki.
To nie jest odosobniony błąd jednego projektu. W marcu ten sam wzorzec znaleziono w oficjalnym SDK MCP dla Javy, gdzie gwiazdka była wpisana na stałe w kodzie transportu, a w oficjalnym SDK dla Go serwer przyjmował międzydomenowe żądania POST bez sprawdzania nagłówka Origin. Specyfikacja MCP od dawna zaleca weryfikację tego nagłówka. Problem w tym, że każda biblioteka i każdy serwer muszą o tym pamiętać osobno.
Przy okazji warto sprawdzić własne maszyny. To polecenie pokazuje procesy nasłuchujące na wszystkich interfejsach:
ss -ltnp | grep -E '0\.0\.0\.0:|\[::\]:|\*:'
LISTEN 0 128 0.0.0.0:9094 0.0.0.0:* users:(("x64dbg",pid=4120,fd=12))
LISTEN 0 511 0.0.0.0:4000 0.0.0.0:* users:(("python3",pid=2231,fd=7))
netstat -ano | findstr LISTENING.Wzorzec trzeci: agent pobiera, co mu każą
Serwer fetch to najprostszy serwer MCP: dostaje adres i zwraca treść strony. Jest częścią oficjalnego repozytorium przykładów protokołu, więc wiele osób zaczyna właśnie od niego. Problem w tym, że adres wybiera model, a model może wybrać ten, który podsunie mu treść przeczytana chwilę wcześniej. Tak wygląda wywołanie, które badacz w zgłoszeniu na GitHubie wykonał na maszynie EC2:
{
"name": "fetch",
"arguments": {
"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/<rola>"
}
}
Wywołanie nie zawiera nic egzotycznego. Agent, którego pośrednio przejęto przez treść, wykona je tak samo jak każde inne. Dlatego SSRF w serwerze, który pobiera adresy wskazane przez model, to nie błąd brzegowy, tylko jego główne ryzyko.
Ciekawsza od samej luki jest jej historia. Projekty, które próbowały się bronić, padały jeden po drugim na różnych szczegółach. Serwer mcp-fetch sprawdzał adres IPv6 razem z nawiasami, więc kontrola adresów prywatnych w ogóle się nie uruchamiała. auth-fetch-mcp przepuszczał adres IPv4 zapisany jako IPv6. mcp-searxng nie sprawdzał ponownie celu przekierowania. MCP Atlassian sprawdzał adres przy walidacji, a łączył się z innym, który zwracał DNS chwilę później. Ten ostatni błąd był obejściem wcześniejszej poprawki. Nawet oficjalny rejestr serwerów MCP miał SSRF w weryfikacji domen wydawców.
Wniosek jest stary jak sam SSRF: listy zakazanych adresów w kodzie aplikacji przegrywają, bo adres da się zapisać na zbyt wiele sposobów. Wygrywa reguła na poziomie sieci. Proces serwera MCP w ogóle nie powinien mieć trasy do adresu metadanych ani do sieci wewnętrznej, chyba że to jego zadanie.
Poprawka przed nazwą
Dwie pozycje z listy mają szczegół, który łatwo przeoczyć. Poprawkę dla Loom wydano 4 sierpnia, a biuletyn z numerem CVE pojawił się 2 października. W Claude Agent SDK poprawka trafiła do PyPI 17 lipca, komunikat bezpieczeństwa ukazał się 12 września, a wpis w NVD dopiero 16 października.
Przez dwa, trzy miesiące skaner szukający znanych numerów CVE nie miał czego znaleźć, a wersja z poprawką była już dostępna. Działa to w obie strony. Kto aktualizuje zależności regularnie, był bezpieczny, zanim luka dostała nazwę. Kto czeka na alarm ze skanera, dowiedział się po kwartale. W ekosystemie, w którym SDK wydaje nowe wersje co tydzień, sama polityka „łatamy, gdy jest CVE” zostaje w tyle.
Co wiemy, a czego nie
Potwierdzone: wszystkie dziewięć luk ma numery CVE i opisy w rekordach CVE lub biuletynach producentów. Dla ośmiu z nich istnieje poprawiona wersja. Próby wykorzystania odnotowano w przypadku Langflow, dla poprzedniej luki tej samej klasy.
Niepotwierdzone: w źródłach, które sprawdziliśmy, żadna z pozostałych luk nie figuruje w katalogu KEV, w którym CISA zbiera podatności wykorzystane w prawdziwych atakach. Nie znamy też przebiegu włamania do GitBooka, a w szczególności nie wiemy, czy serwer MCP miał z nim coś wspólnego. Nie wiemy też, czy poprawka SSRF w mcp-server-fetch została już włączona do wydania. W dniu publikacji CVE czekała na akceptację.
Co to znaczy dla firmy, która wystawia serwer MCP
Na senteri często piszemy, że firmy powinny udostępniać agentom swoje dane i usługi w sposób, który da się przeczytać i wywołać. Serwer MCP to dziś najprostsza droga, żeby to zrobić. GitBook ma taki serwer do swojej dokumentacji, jak wiele innych platform.
Październik przypomina, że serwer MCP jest API, a nie widżetem. Ma uwierzytelnianie, sesje, tokeny, dostęp do sieci i, w wielu wdrożeniach, możliwość uruchamiania procesów. Wymaga tej samej dyscypliny co każde publiczne API: przeglądu bezpieczeństwa przed wdrożeniem, ograniczonego dostępu do sieci, rotacji poświadczeń i miejsca na liście rzeczy do unieważnienia po incydencie. GitBook to miejsce już mu przydzielił. Lepiej zrobić to przed własnym incydentem niż po nim.
Checklista obrońcy
- Spis. Wypisz wszystkie serwery MCP używane w firmie: w IDE, w asystentach kodujących, na serwerach z agentami. Do każdego zapisz wersję, transport (stdio, SSE, HTTP) i właściciela. W generatorze karty agenta AI służy do tego sekcja „Narzędzia i serwery MCP”.
- Konfiguracja jak kod. Pliki
.mcp.jsoni ich odpowiedniki trzymaj w repozytorium, zmieniaj przez przegląd kodu i monitoruj ich zmiany. Agent nie powinien mieć prawa zapisu do konfiguracji własnych narzędzi. - Bez
0.0.0.0. Serwery lokalne mają nasłuchiwać na127.0.0.1i wymagać tokenu. Sam localhost nie wystarczy, jeśli serwer obsługuje SSE i odpowiada gwiazdką w CORS. - Ruch wychodzący domyślnie zablokowany. Proces serwera, który pobiera adresy wskazane przez model, nie może mieć trasy do 169.254.169.254 ani do sieci wewnętrznej. W AWS wymuś IMDSv2.
- Sprawdź, co się dzieje bez konfiguracji. Przy każdej platformie agentowej, którą wdrażasz, sprawdź, czy przy braku dostawcy tożsamości albo polityki odmawia dostępu, czy go przyznaje. Loom i Agent Mesh przyznawały.
- Dane od użytkownika nie trafiają do argumentów CLI. Identyfikatory sesji, nazwy plików i ścieżki przekazywane do narzędzi agentowych sprawdzaj według wzorca, na przykład UUID.
- Aktualizuj według wydań, nie według CVE. SDK i serwery MCP zmieniają się co tydzień, a numery luk przychodzą miesiącami później.
Jedna myśl na drogę
Dwadzieścia lat temu nauczyliśmy się, że formularz na stronie jest drzwiami do serwera, i przez następne dziesięć lat budowaliśmy wokół tych drzwi zamki. MCP to drzwi tego samego rodzaju, tylko otwiera je agent, a nie człowiek, i robi to szybciej, niż ktokolwiek zdąży przeczytać log. Zamki znamy, ich nazwy są w każdym podręczniku. W październiku ich po prostu nie założono.
Źródła
- Decrypt: GitBook Hit by AI Agent Security Breach, Urges Users to Rotate Keys
- OpenCVE: CVE-2026-104120, mcp-server-fetch SSRF
- GitHub, modelcontextprotocol/servers #4143: mcp-server-fetch lacks SSRF protection
- AWS Security Bulletin 2026-124-AWS: Loom for AWS
- OpenCVE: CVE-2026-105697, Langflow
- eSecurity Planet: Kritische Langflow-Schwachstelle unter Angriff
- OpenCVE: CVE-2026-107824, x64dbg-MCP Server
- Penligent: CVE-2026-103572, Visual Studio Copilot and SSMS RCE Explained
- OpenCVE: CVE-2026-96620, Claude Agent SDK
- Issoh: CVE-2026-96620, chronologia poprawki i komunikatu (po japońsku)
- OpenCVE: CVE-2026-103091, Google OSS Agent Mesh
- OpenCVE: CVE-2026-62863, MoLing
- OSV: GHSA-hv2w-8mjj-jw22, MCP Java SDK Hardcoded Wildcard CORS
- GCVE: CVE-2026-33252, Go MCP SDK cross-site POST
- Strix: CVE-2026-116635, aws-serverless-mcp-server
- Lutra Security: CVE-2026-80347, mcp-fetch
- OpenCVE: CVE-2026-49857, auth-fetch-mcp
- OSV: CVE-2026-54689, mcp-searxng
- OSV: CVE-2026-73497, MCP Atlassian
- OffSeq: CVE-2026-44430, MCP Registry SSRF