Kto 21 października 2026 roku między 13:39 a 15:23 czasu polskiego zainstalował LiteLLM z PyPI bez przypiętej wersji albo między 13:46 a 16:20 pobrał i uruchomił obraz Docker z tagiem latest, ma na maszynie program kradnący hasła, klucze chmurowe, sekrety CI/CD i tokeny narzędzi AI. Opiekunowie projektu potwierdzili, że wersję 1.107.0 zbudowano z podrobionego repozytorium po przejęciu kont trzech programistów. Sama aktualizacja niczego nie załatwia, bo każde uruchomienie Pythona w zainfekowanym środowisku, także pip install, odpala złośliwy kod od nowa.
Co się stało z LiteLLM 1.107.0
LiteLLM to biblioteka Pythona i serwer pośredniczący (proxy), przez który aplikacje rozmawiają z wieloma modelami AI jednym interfejsem. W trybie proxy trzyma w swojej bazie klucze API dostawców, na przykład OpenAI czy Anthropic. Według PyPI Stats pakiet pobrano ponad 92 mln razy w ostatnim miesiącu. Liczba obejmuje też ruch automatyczny, między innymi systemy CI i serwery lustrzane, więc nie odpowiada liczbie użytkowników.
Kod źródłowy projektu nie miał błędu. Napastnik przejął proces wydawania paczek. We wpisie o incydencie opiekunowie podają oś czasu w UTC. O 10:08 UTC ochrona gałęzi odrzuciła nieautoryzowaną zmianę w prywatnym procesie wydań. Pięć sekund później konto uprzywilejowanego programisty tę blokadę nadpisało. Proces zbudował wydanie z repozytorium Berri-AI/litellm, czyli z nazwą organizacji z łącznikiem. Prawdziwa organizacja to BerriAI. Drugie konto zatwierdziło bramkę produkcyjną, a trzecie skasowało zapisy przebiegów, co utrudnia dochodzenie.
Opiekunowie piszą, że konta przejęto “najprawdopodobniej” skradzionymi tokenami OAuth narzędzia GitHub CLI. Skąd wyciekły, jeszcze nie wiedzą. W aktualizacji z 18:30 UTC mają “potencjalny wektor” dla jednego tokenu. Z organizacji na GitHubie usunęli wszystkich poza jedną osobą i wstrzymali wydania. Oficjalny znacznik v1.107.0 w repozytorium jest czysty.
Badacze Upwind, którzy zgłosili sprawę, zauważyli, że dziewięć z dziesięciu zmian napastnika miało na GitHubie znaczek “Verified”. GitHub podpisuje tak każdą zmianę zrobioną w jego edytorze w przeglądarce, więc znaczek mówi tylko tyle, że zmianę wprowadzono na github.com.
Kogo dotyczy: kanały, wersje i godziny
Zagrożony jest każdy, kto w podanych oknach pobrał paczkę bez przypiętej wersji albo uruchomił obraz z ruchomym tagiem. Dotyczy to także zespołów, które niczego świadomie nie aktualizowały, a w tym czasie ponownie utworzyły kontener albo pod i pobrały obraz spod ruchomego tagu, albo puściły budowanie w CI. Sam restart istniejącego kontenera bez pobrania obrazu infekcji nie powodował. Godziny podajemy za wpisem opiekunów.
| Kanał | Wersja lub tag | Okno, czas polski (CEST) | Okno UTC | Co zrobić |
|---|---|---|---|---|
PyPI (instalacja przez pip) | 1.107.0, wszystkie 7 plików wheel (Linux, macOS, Windows) | 13:39–15:23 | 11:39–13:23 | traktować środowisko jako przejęte, procedura niżej |
Docker Hub litellm/litellm | v1.107.0, latest, main-latest, main-stable | 13:46–16:20 | 11:46–14:20 | odbudować na v1.106.2 przypiętym skrótem obrazu, zmienić sekrety |
GHCR (GitHub), trzy warianty obrazu: podstawowy, -database, -non_root | te same tagi | 13:46–15:51 | 11:46–13:51 | jak wyżej |
| Prywatny rejestr dla klientów enterprise | – | nie dotyczy | – | według opiekunów bez działań |

Wcześniejsze wersje opiekunowie uznają za bezpieczne i zalecają przypięcie 1.106.2. Dziś to najnowsza wersja w PyPI. Skrót (digest) zainfekowanego indeksu obrazu na Docker Hub to sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e.
Agenci AI · Kodożercy
Zbuduj sobie dział cyfrowych pracowników
Kurs Agenci AI od Kodożerców przeprowadza krok po kroku przez budowanie agentów w n8n. Pięciu agentów, pięć realnych zadań, a przy każdym wariant przeniesienia rozwiązania na Twój własny przypadek.
Sprawdź kurs Agenci AI →
Co kradnie złośliwy kod w wersji 1.107.0
Wydanie dokłada do katalogu site-packages trzy pliki: cook.pth, cook.py i sitecustomize.py. Python wczytuje je przy każdym starcie, nawet gdy program w ogóle nie importuje tej biblioteki. Uruchamia się więc przy aplikacji, przy pip, przy wtyczce edytora i przy zadaniu CI.
Według zgłoszenia #47826 na GitHubie i analizy SafeDep złodziej zbiera:
- zapisane hasła i ciasteczka przeglądarek Chromium oraz dane logowania Firefoksa,
- klucze z
~/.ssh, historie poleceń powłoki, pliki.env, klucze*.pemi*.key, - poświadczenia AWS, Azure, gcloud, Kubernetes, Dockera i GitHub CLI,
- sekrety CI/CD: GitLab Runner, Jenkins, Vault, Terraform,
- tokeny i konfiguracje narzędzi AI: Claude Code, Codex, Gemini CLI, Cursor, Windsurf, Kiro, Copilot, Hugging Face,
- zmienne środowiskowe wszystkich procesów, które może odczytać,
- tymczasowe klucze ról chmurowych z usług metadanych AWS, GCP i Azure.
Najgroźniejszy dla firm jest jeden moduł. Jeśli na maszynie ustawiono zmienną DATABASE_URL, złodziej zrzuca z bazy proxy tabele z kluczami wszystkich dostawców modeli. Dane szyfruje i wysyła na www.litellm.dev. Projekt używa domeny litellm.ai, a tę podróbkę zarejestrowano 13 października.
Drugi plik, sitecustomize.py, uruchamia na Linuksie i macOS proces w tle. Co godzinę miał on czytać adres serwera z pliku na GitHubie, pobierać stamtąd kod i go wykonywać. Według badaczy plik z adresem był pusty, a konto z nim GitHub usunął około 15:30–15:40 czasu polskiego. SafeDep zastrzega jednak, że nie odzyskał adresu serwera i nie wyklucza, że część maszyn zdążyła pobrać drugi etap.
Skradzione klucze już są używane
Wiz podał o 19:05 UTC, że napastnik zaczął korzystać ze skradzionych poświadczeń około 4,5 godziny po ich wysłaniu. Między 18:20 a 19:01 czasu polskiego sprawdzał klucze ról AWS zebrane z przejętych maszyn CI i węzłów Kubernetes w wielu środowiskach. Po wywołaniu GetCallerIdentity pytał o dostępne modele w usłudze Bedrock. Wiz łączy to z tak zwanym LLMjackingiem, czyli uruchamianiem modeli AI na cudzym koncie chmurowym i na cudzy rachunek. W kilku środowiskach napastnik przeglądał też role, użytkowników i klucze w IAM.
Dla właściciela konta AWS oznacza to konkretną czynność: sprawdzić w CloudTrail wywołania GetCallerIdentity z roli instancji w okolicy godziny instalacji, a potem użycie tej roli spoza własnej infrastruktury. Wiz podaje adresy IP napastnika we wpisie.
Jak sprawdzić, czy masz zainfekowaną wersję
Na podejrzanej maszynie nie uruchamiaj Pythona, dopóki nie sprawdzisz plików. Wpis opiekunów podsuwa pip show litellm, ale pip to też Python, więc odpali złodzieja jeszcze raz. Pliki sprawdzisz z poziomu powłoki, na przykład find / -name cook.pth 2>/dev/null, a na Windowsie w PowerShellu przez Get-ChildItem -Path C:\ -Recurse -Force -Filter cook.pth -ErrorAction SilentlyContinue, osobno dla każdego dysku.
Wskaźniki infekcji według opiekunów, Upwind, SafeDep i Wiz:
- katalog
litellm-1.107.0.dist-infowsite-packages, - pliki
cook.pth,cook.pyisitecustomize.pyw katalogusite-packages, - plik
/tmp/.pc_once_72129118c59f5636c0bb, który powstaje dopiero po udanej wysyłce danych, - plik blokady
/tmp/remote_code_loader.locki osierocony procespythonz katalogiem roboczym/, - zmienna środowiskowa
PRIVCOLLECT_ACTIVE=1, - ruch do
www.litellm.dev/healthcheckz nagłówkiemX-Token: XWiA8gZNa7NcX2XRoAEb, - kontener uruchomiony z obrazu o skrócie zaczynającym się od
sha256:1bbcb1443bc9(pełny skrót wyżej).
Znalezienie któregoś z tych śladów potwierdza infekcję. Ich brak jej nie wyklucza: pliki mogły zostać usunięte, katalog /tmp wyczyszczony, a kontener usunięty albo odbudowany.
Co zrobić, jeśli zainstalowałeś wersję 1.107.0
Opiekunowie przyjęli procedurę od zgłaszających. W skrócie, punkt po punkcie:
- Nie zaczynaj od
pip install. Z poziomu powłoki usuńcook.pth,cook.py,sitecustomize.pyoraz pasujące pliki__pycache__/cook*.pycisitecustomize*.pycz każdego dotkniętegosite-packages. - Zabij proces Pythona działający w tle, który trzyma
/tmp/remote_code_loader.lock. - Zainstaluj ponownie wersję 1.106.2. Lepiej odbudować obrazy i środowiska wirtualne od zera.
- Jeśli maszyna miała dostęp do internetu, przyjmij, że dane wyciekły.
- Zmień wszystko, do czego maszyna miała dostęp: rolę IAM instancji, wszystkie klucze dostawców zapisane w bazie proxy, klucz główny i klucze wirtualne proxy, hasło z
DATABASE_URLi każdy sekret ze zmiennych środowiskowych. - Przejrzyj CloudTrail pod kątem
GetCallerIdentityz roli instancji i użycia jej poświadczeń spoza firmy.
Na laptopie programisty lista sekretów do zmiany jest dłuższa. Obejmuje hasła z przeglądarki, klucze SSH i tokeny Claude Code, Codex czy Cursora, bo złodziej zbierał je wprost.
Jak nie wciągnąć kolejnego przejętego wydania
To drugi incydent z łańcuchem wydań tego projektu w 2026 roku. W marcu na PyPI trafiły dwie złośliwe wersje, o czym pisaliśmy przy wycieku danych z Mercora. We wrześniu CISA wpisała do katalogu wykorzystywanych podatności lukę w obsłudze MCP w tej bramce. Bramka do modeli trzyma klucze do wszystkiego, więc jest celem samym w sobie, podobnie jak konsola OpenCode z kluczami API.
Polskie zespoły i software house’y, które stawiają tę bramkę jako jedno wejście do wielu modeli, mogą ograniczyć ryzyko trzema nawykami. Przypinaj wersje w pliku blokady razem z sumami kontrolnymi. Obraz w produkcji pobieraj po skrócie, a ruchome tagi latest i main-stable zostaw na testy. Nowe wydania wpuszczaj do produkcji z kilkudniowym opóźnieniem, bo ta wersja żyła w PyPI niecałe dwie godziny. Upwind zwraca też uwagę, że projekt nigdy nie publikował w PyPI atestacji pochodzenia paczek, więc użytkownik nie miał jak odróżnić podrobionego wydania od prawdziwego.
FAQ
Czy wystarczy zaktualizować pakiet do wersji 1.106.2?
Nie wystarczy. Zmiana wersji nie usuwa plików cook.pth i sitecustomize.py, a samo pip install uruchamia złodzieja jeszcze raz. Trzeba najpierw usunąć pliki z powłoki, zabić proces w tle, a potem zmienić wszystkie sekrety, do których maszyna miała dostęp.
Czy zainfekowana wersja działa na Windowsie i macOS?
Tak. Wszystkie siedem plików wheel, także dla Windowsa i macOS, zawierało złośliwe pliki. Według Upwind na Windowsie nie startuje proces w tle z sitecustomize.py, ale cook.py, czyli sam złodziej, uruchamia się normalnie.
Agent AI, który pracuje na danych Twojej firmy
Budujemy agentów, którzy odpowiadają klientom, czytają dokumenty i przygotowują raporty, podłączonych do Waszych systemów. Zaczynamy od jednego procesu i sprawdzamy efekt, zanim pójdziemy dalej.
Podsumowanie
Przejęta wersja 1.107.0 była dostępna w PyPI od 13:39 do 15:23, a w obrazach Docker do 16:20 czasu polskiego. Kto ją wtedy pobrał, powinien uznać maszynę za przejętą, usunąć pliki z poziomu powłoki i zmienić każdy sekret, który na niej leżał, łącznie z kluczami dostawców modeli w bazie proxy. Według Wiz napastnik już po kilku godzinach sprawdzał skradzione klucze AWS pod kątem dostępu do modeli w Bedrock. Opiekunowie nie znają jeszcze drogi wycieku tokenów, wydania są wstrzymane, a rejestry obrazów zablokowane. Stan na 21 października 2026 roku, godz. 21:40: kolejną aktualizację zapowiedzieli na 22:30 czasu polskiego. Do odwołania warto przypiąć 1.106.2 i nie pobierać ruchomych tagów.
Newsletter · DevstockAcademy & Kodożercy
Bądź na bieżąco ze światem IT, AI i automatyzacji
Co wtorek: newsy z branży, praktyczne tipy i narzędzia które warto znać. Zero spamu.



