Server mcp-searxng posílal heslo k instanci SearXNG klientovi hned po připojení
Prostředník mezi asistentem a vyhledávačem SearXNG posílal ve verzi 1.11.0 celý obsah proměnné SEARXNG_URL, tedy i jméno a heslo v ní zapsané, jako logovací zprávu klientovi. Druhou cestou byla chybová hláška o špatném formátu adresy. Funkci na začernění měl projekt v kódu od konce června, jen ji na těch dvou místech nevolal.

Balíček mcp-searxng stojí mezi asistentem a vyhledávačem SearXNG. Dá modelu dva nástroje, hledání a přečtení zadané adresy, a dotazy za něj vyřídí sám. Kdo si SearXNG provozuje doma nebo ve firmě, mívá ho zavřený za jménem a heslem, a návod k verzi 1.11.0 říká, kam je zapsat: rovnou do adresy v proměnné SEARXNG_URL, tedy ve tvaru https://user:password@search.example.com.
Co se s tou adresou dělo dál, popisuje hlášení GHSA-hjwh-xvfw-qrwj zveřejněné 19. srpna. Číslo CVE nedostalo, závažnost mu autor navrhl střední (CVSS 5,5) a týká se všech vydání pod 1.12.0.
Adresa odešla celá dvěma cestami
První je úvodní hlášení serveru. Jakmile se klient připojí přes standardní vstup a výstup, pošle mu server několik zpráv typu notifications/message o verzi, úrovni logování a prostředí. Poslední z nich začíná slovy SearXNG URLs a nese hodnotu proměnné přesně tak, jak ji server načetl. Tedy včetně jména a hesla. Je to týž kanál, kterým se ke klientovi dostávají výsledky nástrojů.
Druhá cesta vede přes kontrolu formátu. Když se adresa nedala rozebrat, vrátila funkce validateSearxngInstanceUrl hlášku SEARXNG_URL invalid format: a za ní tutéž adresu celou; ta se zapsala do logu a klientovi se vrátila jako chyba JSON-RPC. Server ji navíc při startu vypisoval na chybový výstup, to ale jen tehdy, když ho spustil člověk v terminálu.
Rozdíl proti obyčejnému úniku do logu dělá to, kdo je na druhé straně. Klientem MCP je nástrojová vrstva asistenta, takže heslo k vyhledávači skončí tam, kde se pracuje s textem, který si model odnáší dál.
Začerňovat projekt uměl už měsíc předtím
Nešlo o chybějící funkci. Soubor src/searxng-instances.ts obsahoval už ve verzi 1.11.0 funkci redactSearxngInstanceUrl, která z adresy vyhodí jméno i heslo a vrátí ji bez nich; přibyla tam commitem z 30. června, jehož popis slibuje začernění údajů v chybách, logu a záznamech o původu dat. Na obou místech výš se prostě nezavolala.
Dorovnal to commit z 25. července nazvaný security(diagnostics): redact authentication data: jednadvacet souborů, 1 139 přidaných řádků a nový soubor diagnostic-sanitizer.ts, kterým teď prochází výstup procesu, logovací zprávy MCP, chyby JSON-RPC i diagnostika serveru HTTP. Hláška o špatném formátu adresu už neopakuje vůbec, píše jen pořadí položky. O den později vyšla verze 1.12.0.
V manifestu je proměnná nově označená za tajnou
Změna se nedotkla jen kódu. Soubor .mcp/server.json, kterým se balíček hlásí do registru MCP, měl u SEARXNG_URL ve verzi 1.11.0 příznak isSecret nastavený na false a proměnné AUTH_USERNAME a AUTH_PASSWORD nevypisoval vůbec. Ve verzi 1.12.0 jsou v manifestu všechny tři a všechny mají isSecret: true. Klient, který schéma čte, tak ví, že hodnotu nemá ukazovat ani ukládat.
Za zmínku stojí, že projekt na věc neupozornil až hlášením. Poznámky k vydání 1.12.0 mají vlastní oddíl Security a stojí v něm i věta, že kdo starší verzi provozoval, má po aktualizaci vyměnit přihlašovací údaje a omezit přístup k uloženým logům. Záznam v databázi GitHubu k tomu přibyl o čtyřiadvacet dní později. Že se hlášení a oprava rozejdou o týdny, není u serverů MCP nic výjimečného – u brány ContextForge zná databáze jen jedno hlášení ze čtyř.
Týž den vyšla i dvě hlášení o čtení vnitřních adres
Devatenáctého srpna přibyly u téhož balíčku ještě dva záznamy, CVE-2026-54688 a CVE-2026-54689. Oba míří na nástroj web_url_read, který stáhne zadanou adresu a vrátí ji modelu jako text. Adresu přitom vybírá model, takže ji lze ovlivnit podstrčeným pokynem ve stránce, kterou zrovna čte – podvrženým datům neodolal ani Claude Code, ani Codex.
Pojistka proti vnitřním adresám v kódu byla, jenže se zapínala proměnnou MCP_HTTP_HARDEN, která je vypnutá. Ve výchozím nastavení tedy nástroj sáhl i na smyčku 127.0.0.1 nebo na adresu 169.254.169.254, na které cloudové stroje vydávají metadata instance. Druhý záznam pak popisuje tři způsoby, jak pojistku obejít i po zapnutí: adresou 0.0.0.0, zápisem adresy IPv4 v podobě IPv6 a přesměrováním, jehož cíl se už neověřoval.
Obojí je opravené od verze 1.2.1 ze 7. června, tedy deset týdnů před zveřejněním obou záznamů. Kontrola od té doby běží vždy a vypnout ji jde jen výslovně, proměnnou MCP_HTTP_ALLOW_PRIVATE_URLS, a prochází jí i cíl přesměrování. V dnešní verzi 2.0.0 z 21. srpna je seznam zakázaných rozsahů delší, než hlášení žádalo: vedle privátních rozsahů a smyčky pokrývá i 0.0.0.0/8, adresy typu link-local, sdílený rozsah 100.64.0.0/10 používaný poskytovateli a překrytými sítěmi, testovací rozsahy z dokumentace i protějšky v IPv6.
Co z toho plyne pro provoz
Kdo balíček instaloval kdykoli letos a pak ho neaktualizoval, má nejspíš verzi z doby, kdy platilo aspoň jedno z těch tří hlášení. Na npm je pod značkou latest od 21. srpna verze 2.0.0. Kdo měl heslo k SearXNG napsané v SEARXNG_URL a běžel na 1.11.0 nebo 1.11.1, samotnou aktualizací hotovo nemá: to heslo prošlo přes klienta a přes logy, takže patří vyměnit.
Obecnější poučení z toho plyne jedno. Server MCP posílá klientovi kromě odpovědí nástrojů i svoje logovací zprávy a chybové hlášky, a to je stejný cíl jako výsledek hledání. Co v nich nemá co dělat, tam nesmí ani omylem – a příznak isSecret v manifestu je zatím jediné místo, kde to server umí říct klientovi dopředu.
Zdroje
- SearXNG Basic Authentication Credentials Exposed Through MCP Logs and JSON-RPC Error Responses, databáze hlášení GitHubu, 19. srpna 2026
- SearXNG MCP Server is Vulnerable to SSRF in web_url_read, CVE-2026-54688, 19. srpna 2026
- SearXNG MCP Server: Additional hardened-mode SSRF bypasses, CVE-2026-54689, 19. srpna 2026
- Vydání 1.12.0, poznámky k vydání, 26. července 2026
- src/url-security.ts, zdrojový kód ve verzi 2.0.0
- .mcp/server.json, manifest balíčku ve verzi 1.12.0