Stoat CVE-2026-73057–73059: proxy obrazu otwiera SSRF i DoS, a API omija historię
Trzy CVE w komunikatorze Stoat łączą brakujący adres IPv6, nieograniczony SVG i niespójne uprawnienia wiadomości. Wyjaśniamy poprawkę 0.15.0.
- AUTOR
- Karol Rapacz / CEO Breachroad · OSCP · PNPT
- PUBLIKACJA
- 16 sierpnia 2026
- CZAS CZYTANIA
- 15 min czytania
- TEMAT
- Podatności i CVE
16 sierpnia 2026 roku opublikowano rekordy CVE-2026-73057, CVE-2026-73058 i CVE-2026-73059 dotyczące otwartego komunikatora Stoat, wcześniej znanego jako Revolt. Dwa pierwsze problemy znajdują się w usłudze proxy i przetwarzania mediów January: zdalny obraz SVG może wymusić ogromną alokację pamięci, a nieuwzględniony adres IPv6 :: pozwala ominąć blokadę SSRF i dotrzeć do usług na loopback. Trzeci błąd leży w API Delta i pozwala członkowi kanału pobrać pojedynczą wiadomość mimo odebranego uprawnienia do czytania historii.
Upstreamowe advisory zostały opublikowane wcześniej, 2 sierpnia; wydarzeniem z 16 sierpnia było nadanie i publikacja rekordów CVE. Wszystkie trzy problemy są naprawione w Stoat 0.15.0. Administratorzy instalacji self-hosted powinni sprawdzić wersje wszystkich usług, ponieważ aktualizacja interfejsu lub tylko jednego kontenera nie wymienia automatycznie obrazu January i Delta.
Ten zestaw jest dobrym studium trzech granic. Proxy URL rozdziela Internet od sieci wewnętrznej. Dekoder obrazu rozdziela mały plik wejściowy od kosztu w pamięci. Model uprawnień rozdziela widoczność kanału od możliwości odczytania starszych treści. Każda luka powstała tam, gdzie jedna ścieżka ominęła regułę zastosowaną w ścieżce sąsiedniej.
CVE-2026-73058: brak jednego adresu w blokadzie SSRF
Proxy multimediów pobiera zewnętrzny URL, aby użytkownik nie łączył się bezpośrednio z serwerem obcej treści i aby platforma mogła tworzyć bezpieczniejsze podglądy. Taka funkcja staje się jednak klientem HTTP działającym z perspektywy infrastruktury Stoat. Jeśli przyjmie adres wewnętrzny, napastnik może użyć jej do odczytu usługi niewidocznej z Internetu.
Advisory SSRF wyjaśnia konkretną asymetrię. Blocklista zawierała IPv4 0.0.0.0/8, prywatne zakresy, 127.0.0.0/8, link-local oraz część IPv6, w tym ::1 i ULA. Brakowało jednak IPv6 unspecified ::. Na Linuksie połączenie TCP do tego adresu może zostać skierowane na loopback, więc URL z literalnym IPv6 przechodził walidację, a następnie trafiał do lokalnej usługi.
Endpointy /proxy i /embed były dostępne bez uwierzytelnienia, dlatego atak nie wymagał konta. CVE opisuje odczyt treści dostępnej z loopback usługi January. Faktyczny wpływ zależy od tego, co nasłuchuje lokalnie, czy wymaga uwierzytelnienia i czy odpowiedź proxy zwraca zawartość klientowi.
To przypadek niepełnej poprawki. Wcześniejsze zabezpieczenia uwzględniały rebinding DNS i sprawdzanie rozwiązanego adresu, ale pominęły jeden semantycznie równoważny zapis. Skuteczna ochrona SSRF musi normalizować IPv4, IPv6, adresy mapowane, DNS i przekierowania, a polityka powinna działać jako allowlista dozwolonych miejsc docelowych tam, gdzie jest to możliwe.
CVE-2026-73057: niewielki SVG, ogromny bufor
SVG jest dokumentem tekstowym opisującym grafikę, a nie gotową tablicą pikseli. Pole viewBox może zadeklarować wymiary znacznie większe niż rozmiar pliku przesłanego przez sieć. Podatna ścieżka January przekazywała te wymiary do tworzenia pixmapy bez odpowiedniego górnego limitu.
Advisory CVE-2026-73057 podaje, że obraz 20 000 × 20 000 może potrzebować około 1,4 GB pamięci dla pojedynczego żądania. Wiele równoległych wywołań proxy może więc wyczerpać repliki, wywołać intensywny swapping lub doprowadzić do ich zabicia przez mechanizm OOM.
Limit rozmiaru pobieranego pliku nie wystarcza. Kilkaset bajtów XML może opisywać ogromne płótno. Zabezpieczenie musi sprawdzać szerokość, wysokość, iloczyn pikseli, format kanałów, oczekiwany koszt dekodowania i czas pracy. Najlepiej odrzucać przekroczenie przed alokacją bufora, a sam dekoder uruchamiać w procesie z twardym limitem pamięci.
Wysoka dostępność nie neutralizuje błędu. Jeśli load balancer kieruje kolejne żądania do zdrowych replik, może pomóc napastnikowi rozłożyć koszt na cały klaster. Rate limiting per źródło, globalny limit równoległego dekodowania i kolejka z backpressure są równie ważne jak liczba replik.
CVE-2026-73059: widzę kanał, ale nie powinienem widzieć historii
Stoat rozdziela ViewChannel od ReadMessageHistory. Administrator może pozwolić użytkownikowi widzieć kanał i nowe zdarzenia, ale zabronić przeglądania starych wiadomości. Zbiorcze endpointy wyszukiwania i listowania historii sprawdzały oba znaczenia zgodnie z modelem.
Advisory dotyczące uprawnień wskazuje, że endpoint pobierający pojedynczą wiadomość po identyfikatorze sprawdzał tylko ViewChannel. Członek z odebranym ReadMessageHistory nie mógł listować ani przeszukiwać historii, ale jeśli poznał identyfikator wiadomości, mógł pobrać jej pełną treść.
To poziome naruszenie autoryzacji, nie publiczny odczyt wszystkich wiadomości. Napastnik musi być członkiem z dostępem do kanału, a domyślna konfiguracja zwykle przyznaje oba bity razem. Ryzyko pojawia się w celowo rozdzielonych politykach, na przykład dla nowych członków, kanałów czasowych lub ograniczonego dostępu do archiwum.
Problem przypomina klasyczny BOLA/IDOR, ale sednem nie jest sam przewidywalny identyfikator. Nawet całkowicie losowy ID nie zastępuje kontroli obiektowej. Każdy endpoint zwracający wiadomość — lista, wyszukiwarka, link bezpośredni, cytowanie, eksport, powiadomienie — musi wywoływać tę samą centralną decyzję autoryzacyjną.
Kto jest narażony
Według rekordów CVE podatne są wersje Stoat wcześniejsze niż 0.15.0. Priorytet mają instalacje self-hosted wystawiające January do Internetu oraz organizacje używające niestandardowych ról z rozdzielonym ViewChannel i ReadMessageHistory. W środowisku zarządzanym aktualizację wykonuje operator usługi, ale klient nadal powinien potwierdzić status i przejrzeć własne logi.
Inwentaryzacja musi objąć digesty obrazów kontenerowych, nie tylko tag wydania w panelu. Klaster może mieć część replik na starej wersji po niepełnym rolloutcie. Sprawdź deploymenty, joby okresowe, obrazy w węzłach i politykę wymuszającą niezmienne digesty.
Nie ma w źródłach dowodu masowego aktywnego wykorzystania. Brak publicznego incydentu nie jest jednak powodem do opóźniania aktualizacji, ponieważ endpointy proxy są nieuwierzytelnione, a warunki techniczne są proste do sprawdzenia przez skaner.
Co zrobić teraz
Zaktualizuj wszystkie komponenty Stoat do 0.15.0 lub nowszego wspieranego wydania. Wykonaj rollout z kontrolą digestu, poczekaj na wymianę wszystkich replik i usuń podatne obrazy z prywatnego registry oraz cache węzłów, jeśli procedura organizacji tego wymaga.
Ogranicz egress usługi proxy. January zwykle potrzebuje Internetu, ale nie powinien łączyć się z siecią zarządzającą, metadanymi chmurowymi, control plane klastra, bazami danych ani portami administracyjnymi na loopback. Warstwa sieciowa pozostaje drugą barierą, gdy parser URL ponownie pominie reprezentację adresu.
Na reverse proxy ustaw limity czasu, rozmiaru odpowiedzi i liczby równoległych żądań. W samym dekoderze egzekwuj maksymalną szerokość, wysokość i liczbę pikseli przed alokacją. Osobna pula workerów dla przetwarzania mediów zapobiega odebraniu pamięci API wiadomości.
Przeprowadź przegląd ról. Dla każdego wariantu ViewChannel=yes i ReadMessageHistory=no sprawdź wszystkie ścieżki pobrania wiadomości. Test ma potwierdzić odmowę dla pojedynczego ID, cytowania, wyszukiwania, eksportu i załączników związanych z wiadomością.
Detekcja i analiza historyczna
Dla SSRF szukaj żądań proxy do literalnych IPv6, adresów niesklasyfikowanych jako publiczne, nietypowych portów i odpowiedzi przypominających panel lokalnej usługi. Loguj znormalizowany adres docelowy po DNS i po przekierowaniach, lecz uważaj na tokeny znajdujące się w URL.
Dla SVG monitoruj stosunek rozmiaru pliku do deklarowanych wymiarów, skoki RSS, liczbę OOMKill i restartów January. Nagłe serie takich samych zewnętrznych URL-i w wielu replikach mogą wskazywać automatyczne wyczerpywanie puli.
Dla autoryzacji porównaj odmowy na endpointach historii z późniejszym sukcesem pobrania pojedynczej wiadomości przez to samo konto. Taka korelacja jest silniejszym sygnałem niż sam odczyt po ID, który jest normalną funkcją komunikatora.
Lekcje dla projektantów usług
Blocklista SSRF musi działać na kanonicznym adresie i po każdym przekierowaniu. Powinna obejmować pełne odpowiedniki IPv4 i IPv6, ale tam, gdzie biznes pozwala, lepsza jest allowlista protokołów, portów i publicznych zakresów. Ochrona sieciowa nie powinna zależeć od jednego parsera w aplikacji.
Koszt dekodowania musi być prognozowany z metadanych przed alokacją. Limit bajtów wejściowych nie ogranicza bomb logicznych w SVG, PDF, archiwach czy plikach modelu. Ten sam wzorzec dotyczy pipeline’ów AI, które generują podglądy niezaufanych dokumentów.
Autoryzacja powinna być funkcją domenową wywoływaną przez każdą reprezentację obiektu. Kopiowanie dwóch różnych zestawów if do endpointów niemal gwarantuje rozjazd. Macierz testów ról jest dokumentacją kontraktu i powinna działać w CI.
Fakty i wnioski Breachroad
Faktem jest, że trzy rekordy CVE opublikowane 16 sierpnia opisują nieograniczone renderowanie SVG, SSRF przez IPv6 :: oraz brak ReadMessageHistory na ścieżce pojedynczej wiadomości. Wszystkie wskazują 0.15.0 jako wersję naprawioną. Upstreamowe advisory były dostępne wcześniej, a źródła nie dowodzą masowej eksploatacji.
Wnioskiem Breachroad jest testowanie ścieżek równoważnych, nie tylko pojedynczych poprawek: IPv4 i IPv6, mały plik i kosztowny wynik, lista wiadomości i pobranie jednej wiadomości. Najczęstsza luka znajduje się w pominiętym rodzeństwie zabezpieczonej funkcji.
Zespołom budującym komunikatory, proxy multimediów i API polecamy szkolenia cyberbezpieczeństwa dla organizacji. Niezależną kontrolę SSRF i autoryzacji zapewniają testy penetracyjne aplikacji webowych i API.


