Tři servery MCP dostaly týž den záznam CVE za to, že si neověřovaly volajícího
Dropbox, Timescale a ByteDance mají od 27. srpna 2026 každý svůj záznam CVE k serveru protokolu MCP a příčiny se překrývají. Obě oficiální sady MCP umí odmítnout požadavek, jehož hlavička Host nese cizí jméno, jenže zapnout si tu kontrolu musí autor serveru sám. U ByteDance k tomu přibylo naslouchání na všech síťových rozhraních a nepovinné přihlášení.
Tři záznamy k serverům protokolu MCP vydala databáze bezpečnostních hlášení GitHubu 27. srpna 2026 večer, všechny tři v jedné minutě. Postihly Dash od Dropboxu (CVE-2026-81102), server nad archivem Slacku od firmy Timescale (CVE-2026-81099) a sadu serverů, které vznikly kolem nástroje UI-TARS-desktop od ByteDance (CVE-2026-81735). Tři nesouvisející projekty, tři různí vydavatelé, jedna a táž příčina. Všechny tři ohlásil Avishai Gonen z Pluto Security.

MCP je protokol, kterým agentní nástroje sahají na okolní svět: model si přes něj vyžádá soubor, dotaz do databáze nebo příspěvek ze Slacku. Server bývá malý program, který běží přímo na počítači uživatele a drží jeho přihlašovací údaje ke službě. Právě proto se u něj tak snadno zamění dvě věci: kde program naslouchá a kdo se k němu smí ozvat.
Vazba na loopback sama o sobě nechrání
Dashi nešlo vytknout, kde naslouchá. Server se vázal na smyčkovou adresu, tedy 127.0.0.1, a zvenčí se na něj nikdo nedovolal. Jenže útočník se na něj nemusí dovolat sám. Stačí, aby si zaregistroval jméno, nechal ho ukazovat na 127.0.0.1 a přiměl oběť otevřít stránku pod tím jménem. Prohlížeč pak požadavek pošle na místní adresu, ale v hlavičce Host ponese útočníkovo jméno. Tomuhle postupu se říká převazba DNS a jediná obrana, která proti němu funguje bez přihlášení a bez HTTPS, je zahodit požadavek, jehož hlavička Host není na seznamu povolených jmen.
Dash tu hlavičku nečetl. Podle hlášení tak mohla stránka v prohlížeči návštěvníka volat jeho nástroje na firemní hledání a na detail souboru, a to pod přihlášením k Dropboxu, které si server nese. Známka závažnosti je nízká (VulnCheck 2,3 podle CVSS 4.0), protože útok potřebuje součinnost oběti a týkal se jen síťového režimu; verze, která si s klientem povídá přes standardní vstup, zranitelná nebyla. U serveru nad Slackem vyšla známka 7,6; její vektor u něj počítá s vysokým dopadem nejen na důvěrnost dat, ale i na jejich neporušenost.
Ochranu mají obě sady, jen se musí zapnout
Tady je jádro věci. Dash ani server nad Slackem si nic nedopisovaly – všechno, co potřebovaly, mají oficiální sady protokolu připravené. Jen ne zapnuté. Na volitelnou ochranu, kterou si provozovatel serveru musí zapnout ručně, narazila i rubyová knihovna téhož protokolu.
Python má třídu TransportSecuritySettings a v ní pole enable_dns_rebinding_protection, jehož výchozí hodnota je zapnuto. Kdo ale to nastavení serveru vůbec nepředá, dostane opak: middleware si v takovém případě vyrobí vlastní instanci s ochranou vypnutou a v kódu je u toho vysvětlení, že je to kvůli zpětné slučitelnosti. Výchozí hodnota v datovém typu tedy říká něco jiného než výchozí chování knihovny. Oprava Dashe právě to nastavení dopisuje a povoluje trojici 127.0.0.1, localhost a [::1] na zvoleném portu.
TypeScriptová sada řeší totéž samostatným middlewarem hostHeaderValidation; k dispozici je i zkratka localhostHostValidation(), která propustí jen ta tři jména. Přidat ho do aplikace ale musí autor. Server nad archivem Slacku volal sdílenou pomocnou funkci z vlastního balíku a příslušnou volbu jí nikdy nepředal; oprava ji dopisuje, ovšem s podmínkou – zapíná se jen mimo produkční nasazení. Odůvodnění je přímo v kódu: v produkci server běží pod veřejnými jmény, kde by seznam povolených hostitelů odmítl i poctivý provoz, a prohlížeč oběti se na něj nemá jak dostat.
U ByteDance nešlo jen o převazbu
Třetí hlášení má známku 10,0, tedy nejvyšší možnou. Balíček mcp-http-server, přes který startují servery kolem UI-TARS-desktopu, dosazoval za nezadanou adresu hodnotu '::'. To není smyčka, to jsou všechna rozhraní. Přihlašovací mezivrstva se navíc přidávala jen tehdy, když ji volající předal – a server na spouštění příkazů ani server na přístup k souborům jí nepředávaly nic. První z nich přitom nabízí nástroj run_command, který dostane řetězec od volajícího a pošle ho systému k provedení. Kdo se dostal na port, mohl spouštět příkazy pod účtem, který server pustil, a žádné heslo k tomu nepotřeboval. Do téhož stavu se nedávno dostal i Chainlit, když v něm správce zapnul MCP.
Nápověda k přepínači --host u obou serverů přitom tvrdila, že výchozí hodnota je localhost. Dokumentace tedy popisovala něco jiného, než co program dělal, a správce, který si ji přečetl a spolehl se na ni, žádnou adresu nezadal.
Oprava je z prvního července a na npm nedorazila
Vazbu srovnal návrh změny číslo 1918, sloučený 1. července 2026: výchozí adresa je od něj 127.0.0.1 a nápověda k přepínači to nově říká taky. Záznam CVE k tomu vyšel o osm týdnů později.
Kdo si ale ty servery instaluje z registru npm, opravu nedostane. Poslední zveřejněná verze balíčku mcp-http-server je 1.2.4 z 21. července 2025. Stáhli jsme si ji 27. srpna 2026 a v přeloženém souboru je pořád řádek, který za nezadanou adresu dosadí '::'; přiložené README u přepínače uvádí tutéž hodnotu jako výchozí. Balíček @agent-infra/mcp-server-commands, přes který se server na příkazy obvykle spouští, má na npm poslední vydání 1.2.29 z 15. prosince 2025 a závisí právě na verzi 1.2.4. Číslo verze se v repozitáři od opravy nezvedlo ani u jednoho z nich, takže hranicí zranitelnosti je commit, ne vydání – přesně jak píše hlášení. Za období od 28. července do 26. srpna 2026 registr eviduje u mcp-http-server 16 828 stažení. Rozestup mezi opravou v repozitáři a tím, co dostane uživatel, není u serverů MCP první.
Praktický závěr má dvě části a druhá je ta méně zřejmá. Serveru MCP, který mluví po HTTP, se sluší zadat adresu ručně a nespoléhat na výchozí hodnotu. To ale stačí jen na polovinu problému: Dash byl na smyčce od začátku a stejně dostal číslo CVE. Druhá půlka je seznam povolených jmen v hlavičce Host, a o ten se obě sady MCP samy nepostarají.
Zdroje
- GHSA-p68p-fq8j-3639 (UI-TARS-desktop), GHSA-p943-9hp2-h27q (tiger-slack) a GHSA-37q3-f6jc-625w (Dash) v databázi GitHubu
- Hlášení VulnCheck k UI-TARS-desktopu se známkou CVSS 4.0 a jménem nálezce
- transport_security.py v Python SDK a hostHeaderValidation.ts v TypeScript SDK
- Opravné návrhy změn: UI-TARS-desktop #1918, mcp-server-dash #12, tiger-slack #146
- Záznam balíčku mcp-http-server v registru npm s daty vydání jednotlivých verzí