Strona główna/Blog/LiteLLM 1.107.0: złośliwe wydanie kradło klucze API i hasła
Krytyczna

LiteLLM 1.107.0: złośliwe wydanie kradło klucze API i hasła

Przez kilka godzin 21 października oficjalne wydanie LiteLLM instalowało złodzieja danych uwierzytelniających. Jeśli Wasze CI lub kontenery pobrały wtedy najnowszą wersję, trzeba wymienić klucze.

Opublikowano: 22 października 2026

Pęk starych żelaznych kluczy na drewnianej skrzyni

Złośliwa wersja wyszła oficjalnym kanałem

LiteLLM to popularna biblioteka Pythona i serwer proxy, przez który firmy łączą swoje aplikacje z modelami OpenAI, Anthropic, Google czy Azure. W proxy leżą więc klucze API do wszystkich tych dostawców. 21 października 2026 r. na PyPI i w rejestrach obrazów Docker pojawiło się wydanie litellm 1.107.0, które zawierało skompilowane złośliwe oprogramowanie kradnące dane uwierzytelniające i ładujące zdalny kod. Wydanie zostało podpisane i opublikowane przez prawdziwy proces CI projektu, więc z zewnątrz wyglądało jak zwykła aktualizacja. To drugi incydent tego typu w LiteLLM w tym roku: w marcu złośliwe były wersje 1.82.7 i 1.82.8.

Według wstępnych ustaleń zespołu LiteLLM atakujący zdobył tokeny OAuth GitHub CLI trzech programistów. Jednym z nich zdjął ochronę gałęzi i zmienił workflow wydania, drugim zatwierdził publikację, trzecim usuwał ślady uruchomień. Kod do zbudowania wydania pobrano z repozytorium Berri-AI/litellm, różniącego się od oryginalnego BerriAI/litellm jednym myślnikiem. Źródłem tokenów według zespołu były logi wewnętrznej instancji LiteLLM wystawionej do internetu (to wciąż podejrzenie): Claude Code potrafi umieścić token GitHub CLI użytkownika w treści odpowiedzi, a jeśli bramka AI loguje treść odpowiedzi, token trafia do logów. Sposób wejścia na tę instancję nie jest potwierdzony; LiteLLM wskazuje na niedawno załataną podatność. Numer CVE nie został nadany.

Co robi złośliwy kod

Paczka zapisuje w katalogu site-packages pliki cook.pth, cook.py i sitecustomize.py. Python wykonuje je przy każdym starcie interpretera, także wtedy, gdy żaden skrypt nie importuje LiteLLM. Złośliwy kod zbiera dane logowania do AWS, Azure, Google Cloud, Kubernetes i Dockera, poświadczenia Git, klucze SSH i GPG, dane z przeglądarek, historię powłoki, pliki uwierzytelniające Claude, Codex, Gemini i Cursor oraz klucze dostawców z bazy danych proxy LiteLLM. Dane są szyfrowane i wysyłane na adres podszywający się pod domenę projektu. Na Linuksie i macOS drugi moduł działa jako proces w tle i co godzinę sprawdza plik na GitHubie w poszukiwaniu adresu, z którego pobierze kolejny kod.

Okno ataku i wersje

  • Złośliwa: litellm==1.107.0 na PyPI (wszystkie siedem plików wheel), dostępna 21.10 od 11:39 do 13:23 UTC.
  • Docker Hub: tagi v1.107.0, latest, main-latest, main-stable od 11:46 do 14:20 UTC; digest indeksu zaczyna się od sha256:1bbcb1443bc9.
  • GHCR: te same tagi obrazów litellm, litellm-database, litellm-non_root od 11:46 do 13:51 UTC.
  • Bezpieczna: 1.106.2 i każda jawnie przypięta wersja wydana przed incydentem. Klienci prywatnego rejestru Enterprise nie byli objęci atakiem.

Kto mógł to pobrać

Okno trwało niecałe trzy godziny, więc najbardziej narażone są systemy, które same pobierają najnowszą wersję: pipeline’y CI instalujące litellm bez numeru wersji, kontenery uruchamiane z tagiem latest lub main-stable i restartowane w tym czasie, środowiska programistów, którzy akurat robili aktualizację. Jeśli macie wersję przypiętą w pliku blokady albo digest obrazu, prawdopodobnie Was to ominęło.

Jak sprawdzić swoje środowiska

  • W każdym virtualenv i kontenerze: pip show litellm albo pip list | grep -i litellm.
  • Pliki blokady i wymagań: grep -rn "1.107.0" requirements*.txt poetry.lock uv.lock Pipfile.lock.
  • Ślady w systemie: find / -name 'cook.pth' -o -name 'cook.py' -o -name 'litellm-1.107.0.dist-info' 2>/dev/null oraz nietypowe pliki sitecustomize.py w site-packages.
  • Proces w tle: ls -l /tmp/remote_code_loader.lock i ps aux | grep python.
  • Obrazy: docker images --digests | grep litellm i porównanie z digestem podanym wyżej; logi CI z 21.10 między 11:39 a 14:20 UTC.

Brak tych śladów nie dowodzi, że system jest czysty, o czym uprzedza sam producent.

Co zrobić, jeśli wersja 1.107.0 została uruchomiona

  1. Nie zaczynajcie od pip install w zainfekowanym środowisku: każde uruchomienie Pythona ponownie wykonuje złośliwy kod.
  2. Usuńcie pliki cook* i sitecustomize* wraz z plikami .pyc z każdego site-packages i zabijcie proces w tle. Lepiej przebudować obraz lub virtualenv od zera z litellm==1.106.2.
  3. Jeśli host miał dostęp do internetu, przyjmijcie, że dane wyciekły. Wymieńcie wszystkie klucze dostawców LLM zapisane w proxy, klucz główny i klucze wirtualne LiteLLM, hasło z DATABASE_URL, rolę IAM instancji, tokeny GitHub, klucze SSH i każdy sekret ze zmiennych środowiskowych na tym hoście.
  4. W AWS przejrzyjcie CloudTrail pod kątem wywołań GetCallerIdentity z czasu instalacji, użycia kluczy spoza Waszej infrastruktury i nieoczekiwanego ruchu w Amazon Bedrock. U dostawców LLM sprawdźcie zużycie i rachunki.

Logi bramki AI to też magazyn sekretów

Ten incydent pokazuje dwie rzeczy. Po pierwsze, podpisane wydanie z oficjalnego CI nie gwarantuje bezpieczeństwa, dlatego wersje i digesty obrazów trzeba przypinać, a aktualizacje zależności wdrażać z kilkudniowym opóźnieniem. Po drugie, bramka AI, która loguje pełne zapytania i odpowiedzi, zbiera w logach wszystko, co agenci programistyczni i użytkownicy do niej wyślą, łącznie z tokenami. Takie logi wymagają maskowania sekretów, krótkiej retencji i dostępu tylko dla wąskiej grupy osób, a sama bramka nie powinna być dostępna z internetu.

Chcecie mieć to z głowy?

W ramach stałej opieki IT pilnujemy aktualizacji i reagujemy na nowe podatności, zanim ktoś je wykorzysta.

Umów konsultację