Strona główna / Blog / Mercury (Jupyter): trzy CVE, jeden cel

Blog · analiza

Mercury (Jupyter): dwa RCE bez logowania i XSS. Trzy wersje naprawcze, CVE dwa miesiące po poprawkach i jeden właściwy cel

Mercury to framework, który zamienia notatniki Jupyter w aplikacje internetowe i dashboardy. Uruchomiony bez tokenu wystawia serwer Jupyter dla anonimowych użytkowników, a niebezpieczne endpointy zasłania blocklistą. 19 października 2026 GitHub opublikował dla niego trzy CVE: dwa zdalne wykonania kodu bez uwierzytelnienia (10.0 i 9.8) i XSS (6.1). Poprawki wyszły w sierpniu i wrześniu, w trzech różnych wersjach. Druga luka działała jeszcze na wersji, która naprawiła pierwszą. Jeśli zamykasz CVE po kolei, w pewnym momencie będziesz miał „załatany” Critical na podatnym serwerze.

Produkt: Mercury (mljar), pakiet PyPI mercury, framework do publikowania notatników Jupyter jako aplikacji. Używany głównie przez zespoły danych i analityków.
CVE: CVE-2026-111057, CVE-2026-111058, CVE-2026-111059, CNA GitHub, opublikowane 19.10.2026. Źródłowe GHSA z 21.08, 31.08 i 11.09.2026.
Ocena: CVSS 3.1 10.0, 9.8 i 6.1 (CNA). W NVD statusy „Deferred” i „Awaiting Analysis”, tylko oceny GitHub.
Warunek dla RCE: domyślne wdrożenie bez tokenu (brak --token / MERCURY_TOKEN) i dostęp sieciowy do serwera Mercury.
Poprawka zbiorcza: 3.2.11 (10.09.2026), najnowsza wersja na PyPI w dniu weryfikacji.
Threat state: brak w CISA KEV (katalog 2026.10.21, sprawdzony 22.10.2026). SSVC CISA ADP dla CVE-2026-111058: Exploitation: none, Automatable: yes, Technical Impact: total. EPSS ok. 0,004 (20.10). Nie znalazłem informacji o wykorzystaniu w atakach. GHSA zawierają szczegółowe PoC.

Trzy CVE, trzy poprawki

CVE / GHSASkutekCVSS 3.1Zakres podatnyPoprawka (data)CVE opublikowane
CVE-2026-111057
GHSA-f8c7-rwf9-fmgm
RCE bez uwierzytelnienia przez API terminali Jupyter (obejście blocklisty, CWE-185, CWE-284)10.0 (S:C)≥ 3.0.0, < 3.2.43.2.4 (21.08.2026)19.10.2026
CVE-2026-111058
GHSA-rv4m-xm3f-3ccq
RCE bez uwierzytelnienia przez API jąder Jupyter (CWE-862). Potwierdzone na 3.2.49.8< 3.2.6 (bez dolnej granicy)3.2.6 (28.08.2026)19.10.2026
CVE-2026-111059
GHSA-2658-85cv-9wwq
Stored / DOM XSS w widżecie mr.Markdown (CWE-79, CWE-116)6.1 Medium (UI:R)≥ 3.0.0, < 3.2.113.2.11 (10.09.2026)19.10.2026

Warto zwrócić uwagę na dwie rzeczy, których brakuje w prostym zestawieniu „trzy CVE, aktualizuj”. Po pierwsze, XSS ma 6.1 Medium i wymaga interakcji ofiary. Nie stawiaj go na równi z dwoma RCE w SLA. Po drugie, zakres CVE-2026-111058 nie ma dolnej granicy („< 3.2.6”), podczas gdy dwa pozostałe zaczynają się od 3.0.0. Czy dotyczy to starszej linii Mercury 2.x, nie sprawdziłem. Jeśli masz takie instalacje, nie zakładaj, że są poza zakresem.

Dlaczego pierwsza poprawka nie wystarczyła

Mercury, uruchomiony bez tokenu, ustawia według GHSA-rv4m pusty token tożsamości Jupyter i wyłącza sprawdzanie XSRF. Każdy, kto dosięgnie portu, jest dla serwera Jupyter uprawnionym użytkownikiem. Przed niebezpiecznymi endpointami chroni tylko lista zablokowanych ścieżek BLOCKED_PATTERNS.

  • CVE-2026-111057: w tej liście brakowało przecinka. Python skleja sąsiadujące literały tekstowe, więc dwie reguły (dla /lab i /api/terminals) stały się jedną, która nie pasowała do żadnej rzeczywistej ścieżki. API terminali było otwarte, a terminal Jupyter to powłoka systemowa z uprawnieniami procesu. Poprawka w 3.2.4 dodała przecinek.
  • CVE-2026-111058: przecinek nie pomógł na /api/kernels. Tej ścieżki nie da się zablokować, bo Mercury potrzebuje jąder do uruchamiania notatników. Anonimowy klient mógł więc utworzyć jądro i wysłać do niego dowolny kod Pythona. Zgłaszający potwierdził to na wersji 3.2.4, na której terminale były już zablokowane. GHSA mówi wprost: „The blocklist approach is fundamentally unable to cover kernels”.
  • CVE-2026-111059: osobna klasa błędu. mr.Markdown zamieniał Markdown na HTML bez sanityzacji i wstawiał go do widżetu ipywidgets.HTML. Jeśli aplikacja wyświetla dane od użytkowników, z bazy albo z odpowiedzi zewnętrznego API (także modelu LLM), skrypt wykona się w przeglądarce innego użytkownika.

Pierwsze dwa CVE to nie dwa numery jednego błędu, tylko przykład niepełnej naprawy granicy zaufania: poprawiono konkretną regułę, a nie założenie, że anonimowy użytkownik serwera Jupyter może być bezpieczny. Ten sam wzorzec opisywałem przy pgAdmin i vm2. Na czym dokładnie polega poprawka w 3.2.6 (domyślne wymaganie tokenu czy filtrowanie komunikatów do jądra), nie udało mi się potwierdzić. Dlatego niżej zalecam konfigurację tokenu niezależnie od wersji.

Status „patched” per CVE wprowadza w błąd

Wersja w produkcji111057 (terminale)111058 (jądra)111059 (XSS)Status w VM
≤ 3.2.3podatnapodatnapodatnaCritical, RCE bez logowania
3.2.4 – 3.2.5naprawionapodatnapodatnaNadal Critical, choć ticket 111057 jest zamknięty
3.2.6 – 3.2.10naprawionanaprawionapodatnaMedium, zależnie od tego, czy aplikacja wyświetla niezaufane dane
≥ 3.2.11naprawionanaprawionanaprawionaZamknięte, jeśli dodatkowo sprawdzona konfiguracja dostępu

Najgroźniejszy jest drugi wiersz. Zespół, który w sierpniu zaktualizował Mercury do 3.2.4 po GHSA-f8c7, miał w rejestrze zamknięte RCE z oceną 10.0, a serwer nadal pozwalał anonimowo wykonać kod. Od 19 października to widać, bo CVE-2026-111058 ma numer. Przez prawie dwa miesiące między poprawką a CVE skaner oparty na NVD nie pokazywał nic. Podobne opóźnienie CVE względem poprawki opisywałem przy Nextcloud z Collabora CODE. Dla pakietów PyPI lepszym źródłem jest baza GHSA (OSV), w której te zgłoszenia były od sierpnia i września.

Gdzie szukać Mercury

Mercury rzadko trafia do CMDB jako „aplikacja”. To zwykle pakiet w środowisku analityka albo kontener postawiony przez zespół danych, żeby pokazać dashboard biznesowi. Szukaj:

  • pakietu mercury w SBOM-ach obrazów kontenerów, plikach requirements.txt, pyproject.toml i środowiskach conda,
  • procesów mercury run na serwerach i maszynach wirtualnych zespołów danych,
  • usług HTTP z interfejsem Mercury w skanach sieci wewnętrznej i zewnętrznej, szczególnie wystawionych bez reverse proxy z uwierzytelnianiem.

Uwaga na nazwę: mercury na PyPI to krótka i ogólna nazwa. Przy dopasowaniu w SBOM sprawdzaj, czy pakiet pochodzi z repozytorium mljar, a nie z innego projektu o podobnej nazwie.

Jeśli instancja była osiągalna z sieci

Dla RCE bez uwierzytelnienia, zautomatyzowanego według SSVC, publicznie wystawiona instancja na wersji < 3.2.6 to kandydat do oceny kompromitacji, nie tylko do aktualizacji. Zachowaj logi reverse proxy (żądania do API terminali i jąder spoza normalnego ruchu aplikacji), telemetrię procesów potomnych serwera (powłoki, nietypowe procesy Pythona, połączenia wychodzące) i sprawdź, do jakich sekretów miało dostęp konto usługi: zmienne środowiskowe, poświadczenia baz danych, klucze do API. Zespoły danych często trzymają w tych środowiskach bezpośrednie poświadczenia do hurtowni danych. Do potwierdzenia poprawki nie uruchamiaj publicznych PoC na produkcji. Wystarczy kontrola wersji, konfiguracji tokenu i reguł proxy, a testy rób w laboratorium.

Co powinien zrobić VE

  1. Jeden ticket na produkt, nie trzy na CVE. Cel: Mercury ≥ 3.2.11, potwierdzony w uruchomionym procesie lub obrazie, nie w pliku zależności.
  2. Konfiguracja jako część kryterium zamknięcia: ustawiony token (MERCURY_TOKEN / --token) albo reverse proxy z rzeczywistym uwierzytelnianiem, oraz brak bezpośredniej ekspozycji portu w internecie.
  3. Priorytety: instancje osiągalne z sieci na wersji < 3.2.6 jako Critical z oceną kompromitacji. Instancje 3.2.6–3.2.10 jako Medium, wyżej, jeśli aplikacja wyświetla przez mr.Markdown dane od użytkowników lub z LLM.
  4. Przegląd rejestru: wyszukaj findingi GHSA-f8c7 / CVE-2026-111057 zamknięte na 3.2.4 lub 3.2.5 i otwórz je ponownie pod CVE-2026-111058.
  5. Źródła: dla ekosystemu PyPI monitoruj GHSA/OSV, nie tylko NVD.

Powiązane na blogu

Źródła

  • GitHub — GHSA-f8c7-rwf9-fmgm (CVE-2026-111057, /api/terminals, poprawka 3.2.4) — github.com
  • GitHub — GHSA-rv4m-xm3f-3ccq (CVE-2026-111058, /api/kernels, potwierdzenie na 3.2.4, poprawka 3.2.6) — github.com
  • GitHub — GHSA-2658-85cv-9wwq (CVE-2026-111059, XSS w mr.Markdown, poprawka 3.2.11) — github.com
  • CVE.org — CVE-2026-111057 (CNA GitHub, CWE-185, CWE-284, CVSS 10.0) — cve.org
  • CVE.org — CVE-2026-111058 (CNA GitHub, CWE-862, CVSS 9.8, SSVC CISA ADP) — cve.org
  • CVE.org — CVE-2026-111059 (CNA GitHub, CWE-79, CWE-116, CVSS 6.1) — cve.org
  • PyPI — historia wydań pakietu mercury (daty 3.2.4, 3.2.6, 3.2.11) — pypi.org
  • CISA Known Exploited Vulnerabilities Catalog (brak trzech CVE w wersji 2026.10.21) — cisa.gov

Nota redakcyjna: wpis powstał na podstawie szkicu VMRT Radar z 19 października 2026 i został zweryfikowany ze źródłami pierwotnymi 20 października 2026 (ok. 19:15 CEST): rekordy CVE.org trzech CVE (CNA GitHub, daty, CWE, zakresy wersji, CVSS 3.1, SSVC CISA ADP), GHSA-f8c7-rwf9-fmgm, GHSA-rv4m-xm3f-3ccq i GHSA-2658-85cv-9wwq przez GitHub API (daty publikacji, zakresy, opis mechanizmu, potwierdzenie CVE-2026-111058 na 3.2.4), historia wydań na PyPI (daty 3.2.4, 3.2.6, 3.2.11), NVD API 2.0 (statusy „Deferred” i „Awaiting Analysis”), katalog CISA KEV 2026.10.16 i API EPSS. 22 października 2026 (ok. 22:40 CEST) ponownie sprawdziłem KEV: w katalogu 2026.10.21 nadal brak wszystkich trzech CVE. Względem szkicu dodałem ocenę 6.1 Medium dla XSS, daty poprawek i opublikowania GHSA, brak dolnej granicy zakresu CVE-2026-111058 oraz dane SSVC. Nie potwierdziłem: mechanizmu poprawki w 3.2.6 (czy wprowadza domyślny token), tego, czy podatna jest linia Mercury 2.x, wykorzystania w atakach ani liczby instancji wystawionych w internecie. Priorytety, kryterium zamknięcia i zalecenie konfiguracji tokenu niezależnie od wersji to oceny autora.

Zapamiętaj jedno

Mercury, który wystawia notatniki Jupyter jako aplikacje, domyślnie działa bez tokenu i chroni się blocklistą. CVE-2026-111057 (10.0, terminale) naprawiono w 3.2.4, ale CVE-2026-111058 (9.8, jądra) działało dalej na 3.2.4 i zniknęło dopiero w 3.2.6. XSS CVE-2026-111059 (6.1) naprawiono w 3.2.11. Poprawki są z sierpnia i września, CVE z 19 października. Zrób jeden ticket z celem ≥ 3.2.11 i wymogiem tokenu albo proxy z uwierzytelnianiem, otwórz ponownie findingi zamknięte na 3.2.4 i oceń kompromitację instancji osiągalnych z sieci.