LoLLMs CVE-2026-10595: nieuwierzytelniony odczyt plików przez trasę SPA
Zakodowane sekwencje katalogowe omijały normalizację Starlette, a pathlib wychodził poza katalog interfejsu. LoLLMs przed wersją 3 wymaga aktualizacji.
- AUTOR
- Karol Rapacz / CEO Breachroad · OSCP · PNPT
- PUBLIKACJA
- 9 sierpnia 2026
- CZAS CZYTANIA
- 10 min czytania
- TEMAT
- Bezpieczeństwo AI
9 sierpnia 2026 roku opublikowano CVE-2026-10595 w LoLLMs, platformie do pracy z lokalnymi i zdalnymi modelami językowymi. Nieuwierzytelniony użytkownik mógł wykorzystać trasę typu catch-all dla aplikacji SPA do odczytu dowolnego pliku dostępnego dla procesu serwera. Problem dotyczy wersji 2.1.0 i — według zakresu CNA — wydań starszych niż wersja 3. Ocena CVSS 3.0 wynosi 7,5: atak jest sieciowy, prosty, bez logowania i interakcji użytkownika, a bezpośrednim skutkiem jest wysoki wpływ na poufność.
To dobry przykład luki, która nie znajduje się w modelu, promptach ani mechanizmie RAG. Powstała w zwykłej funkcji dostarczającej statyczne pliki interfejsu webowego. System AI dziedziczy całą powierzchnię aplikacji: router HTTP, parser URL, system plików, uprawnienia procesu i sekrety potrzebne do łączenia z modelami.
Gdzie powstał błąd
Rekord CVE-2026-10595 wskazuje backend/routers/ui.py i trasę obsługującą ścieżki aplikacji jednostronicowej. Podatna implementacja łączyła kontrolowaną przez użytkownika ścieżkę z katalogiem plików statycznych. Zakodowane w URL sekwencje przejścia do katalogu nadrzędnego mogły ominąć normalizację ścieżki wykonywaną wcześniej przez Starlette, a następnie zostać rozpoznane przez pathlib w Pythonie.
W efekcie dwa komponenty interpretowały ten sam input na różnych etapach:
- warstwa routingu uznawała ścieżkę za poprawną wartość dla parametru catch-all;
- operacja systemu plików rozwiązywała ją do rzeczywistej lokalizacji poza katalogiem frontendu;
- kod sprawdzał istnienie pliku, ale nie potwierdzał, że rozwiązana ścieżka nadal należy do dozwolonego katalogu.
To klasyczny błąd kanonikalizacji. Filtrowanie samego ciągu przed pełnym dekodowaniem nie daje gwarancji, że późniejsza warstwa zobaczy ten sam ciąg. Kontrola bezpieczeństwa powinna działać na kanonicznej, rozwiązanej ścieżce i sprawdzać jej relację do kanonicznego katalogu bazowego.
Jak działa poprawka
Commit naprawczy LoLLMs wprowadza małą, ale istotną zmianę. Kod najpierw rozwiązuje STATIC_DIR do ścieżki kanonicznej, następnie rozwiązuje ścieżkę kandydata, a na końcu wywołuje is_relative_to(). Jeżeli kandydat nie znajduje się pod katalogiem statycznym, aplikacja zwraca 404.
Ta kolejność jest ważna. Porównywanie surowych prefiksów tekstowych bywa błędne: katalog /app/static-old zaczyna się od podobnego ciągu jak /app/static, a dowiązania symboliczne mogą zmienić rzeczywistą lokalizację. resolve() wraz z kontrolą relacji sprawdza obiekt, który faktycznie zobaczy system plików.
Zmiana została włączona do repozytorium 1 czerwca, natomiast publiczny rekord CVE opublikowano dziś. CNA wskazuje wersję 3 jako granicę naprawy. Organizacja powinna opierać decyzję na zainstalowanym wydaniu, a nie wyłącznie na dacie commita w głównej gałęzi.
Co napastnik mógłby odczytać
CVE potwierdza dowolny odczyt plików w granicach uprawnień procesu LoLLMs. Dokładna zawartość zależy od sposobu instalacji. Potencjalnie istotne są pliki konfiguracyjne, zmienne środowiskowe zapisane w plikach, tokeny do dostawców modeli, dane połączeń, historia aplikacji, klucze usługowe i informacje systemowe.
Nie każdy taki plik istnieje w każdym wdrożeniu i publiczne źródła nie potwierdzają kradzieży konkretnych sekretów. To lista celów, które zespół powinien uwzględnić w ocenie wpływu. Kontener uruchomiony z szerokimi mountami lub konto usługi z dostępem do katalogów użytkowników znacznie powiększa skutki pojedynczego błędu w trasie HTTP.
W aplikacji AI sekret może otwierać kolejną granicę: płatne API modelu, obiektowy magazyn dokumentów, bazę wektorową albo narzędzie agenta. Dlatego odpowiedź nie może kończyć się stwierdzeniem „atakujący tylko czytał pliki”. Trzeba ustalić, jakie uprawnienia niosły dane możliwe do odczytu.
Kto powinien reagować
Priorytet mają instancje LoLLMs starsze niż 3, które nasłuchują poza localhost, są publikowane przez reverse proxy albo mogą być osiągnięte z niezaufanej sieci. Instancja dostępna wyłącznie w sieci firmowej nadal może być celem użytkownika wewnętrznego, przejętego hosta lub żądania wygenerowanego przez inną aplikację.
Sprawdź także kopie laboratoryjne i stacje deweloperskie. Narzędzia AI często zaczynają jako lokalny eksperyment, a później otrzymują tunel, regułę firewalla albo port przekazany z kontenera. Formalny właściciel usługi może nie wiedzieć, że testowa instancja jest osiągalna z sieci.
Plan naprawy i dochodzenia
- Zaktualizuj LoLLMs do wersji 3 lub nowszej i zweryfikuj, że działający proces korzysta z nowego obrazu lub środowiska.
- Do czasu aktualizacji ogranicz dostęp na firewallu i reverse proxy do zaufanych adresów; traktuj to jako mitygację, nie poprawkę.
- Zidentyfikuj wszystkie pliki, katalogi i sekrety czytelne dla konta procesu, w tym mounty kontenera.
- Zachowaj surowe logi HTTP z oryginalnym targetem żądania. Proxy może znormalizować ścieżkę przed zapisaniem jej w logu aplikacji.
- Wyszukaj nietypowe kodowanie URL, powtarzane odpowiedzi plikowe i żądania do trasy SPA, które nie odpowiadają zasobom frontendu.
- Jeżeli podatna instancja była osiągalna, obróć tokeny i hasła możliwe do odczytu oraz przejrzyj ich użycie po stronie usług docelowych.
- Uruchamiaj usługę z oddzielnym kontem, minimalnymi mountami tylko do odczytu i bez dostępu do katalogu domowego administratora.
Jak policzyć rzeczywisty wpływ na sekrety
Zacznij od tożsamości procesu, a nie od zgadywania nazw plików. Ustal UID lub konto systemowe, bieżący katalog, katalog domowy, zmienne środowiskowe, mounty kontenera oraz wolumeny współdzielone z innymi usługami. Następnie zbuduj listę plików, które konto może czytać, ale nie kopiuj ich zawartości do zwykłego zgłoszenia. Raport powinien klasyfikować rodzaj sekretu, właściciela, zakres uprawnień i datę ostatniej rotacji.
Dla każdego sekretu odpowiedz na cztery pytania: czy był obecny w czasie ekspozycji, czy proces mógł go odczytać, czy logi usługi docelowej pokazują jego nietypowe użycie i czy można go bezpiecznie unieważnić. Token do API modelu może oznaczać koszt i dostęp do historii projektu; poświadczenie bazy wektorowej może otwierać dokumenty RAG; klucz do object storage może obejmować znacznie więcej niż jedna aplikacja. Wpływ zależy od polityki po stronie docelowej, nie od samej nazwy pliku.
Rotację wykonuj w kolejności ograniczającej przerwy: najpierw utwórz nowy sekret, nadaj mu minimalny zakres, wdroż go do poprawionej instancji, potwierdź działanie, a dopiero potem unieważnij stary. Jeżeli źródło sekretu mogło być modyfikowane przez napastnika, samo podstawienie wartości nie wystarcza — trzeba sprawdzić mechanizm uruchamiania, obrazy, pliki usług i zadania zaplanowane.
Warstwy ochronne poza poprawką aplikacji
Reverse proxy może wymagać uwierzytelnienia przed dostępem do LoLLMs, ograniczać rozmiar i szybkość żądań oraz zachowywać oryginalny target w chronionym logu. Firewall powinien ograniczać źródła, a host lub kontener nie powinien widzieć sieci zarządzającej bez potrzeby. Żadna z tych kontroli nie zastępuje wersji 3, lecz zmniejsza prawdopodobieństwo i skutki kolejnego błędu w warstwie webowej.
System plików daje równie ważne mechanizmy. Obraz aplikacji może być tylko do odczytu, katalog roboczy osobnym wolumenem, a sekrety dostarczane przez mechanizm, który nie zapisuje ich obok kodu. Profile AppArmor, SELinux lub polityka kontenera mogą ograniczyć odczyt do konkretnych katalogów. Ważne, aby kontrolę przetestować z tożsamością procesu — deklaracja w pliku wdrożeniowym nie dowodzi, że działa na uruchomionym hoście.
Na końcu dodaj test ekspozycji do pipeline’u infrastruktury. Po każdej zmianie obrazu, proxy lub routingu automatyczna kontrola powinna potwierdzić, że usługa nie stała się publiczna, a proces nie otrzymał nowego szerokiego mountu. Wiele incydentów zaczyna się nie od zmiany kodu, lecz od „tymczasowego” udostępnienia portu na potrzeby demonstracji.
Test regresji dla zespołu deweloperskiego
Test powinien objąć zwykłe zasoby SPA, ścieżki znormalizowane, wielokrotne kodowanie, separatory różnych platform, ścieżki bezwzględne i dowiązania symboliczne. Oczekiwanym rezultatem dla każdej wartości wychodzącej poza katalog bazowy jest ten sam bezpieczny błąd, bez informacji o istnieniu pliku.
Kontrolę należy umieścić w jednej funkcji odpowiedzialnej za bezpieczne łączenie ścieżek, a nie powielać w każdym endpointcie. Dodatkowo proxy i framework powinny mieć test integracyjny, ponieważ test jednostkowy samej funkcji nie ujawnia różnic w liczbie dekodowań URL.
Fakty a wnioski Breachroad
Faktem jest nieuwierzytelniony odczyt plików przez zakodowane przejście katalogowe, zakres przed wersją 3, wynik CVSS 7,5 i poprawka oparta na rozwiązaniu oraz kontroli zawierania ścieżki. Publiczne źródła nie potwierdzają wykorzystania luki w kampanii ani odczytu konkretnych danych.
Wniosek Breachroad: bezpieczeństwo AI obejmuje wszystkie zwykłe granice aplikacji, a duże uprawnienia procesu potęgują niewielki błąd webowy. Szkolenia z bezpiecznego wdrażania AI powinny łączyć modele z AppSec i administracją, a audyt bezpieczeństwa AI może sprawdzić ekspozycję, sekrety, mounty i uprawnienia procesu całego stosu.


