Keamanan

LiteLLM 1.107.0 di PyPI Tercemar Credential Stealer, Cek Versi Kamu

LiteLLM 1.107.0 di PyPI Tercemar Credential Stealer, Cek Versi Kamu

Rilis LiteLLM 1.107.0 di PyPI membawa credential stealer dan backdoor remote code execution. Ketujuh wheel-nya, mencakup Linux, macOS, dan Windows, memasang tiga file ke site-packages yang dijalankan setiap kali proses Python start, bahkan proses yang tidak pernah mengimpor litellm. Kode sumber di GitHub tidak memuat file-file itu. PyPI sudah menghapus rilis tersebut, dan versi 1.106.2, 1.107.0rc1, serta 1.107.0rc2 dinyatakan bersih. Temuan ini dipublikasikan SafeDep pada 21 Oktober 2026.

TL;DR

  • LiteLLM 1.107.0 di PyPI memuat tiga file berbahaya, termasuk cook.pth berukuran 12 byte.
  • Stealer mengambil kunci SSH, kredensial cloud, secret CI/CD, token AI, dan password browser.
  • sitecustomize.py memasang daemon yang tiap jam mengambil alamat server dari file GitHub.
  • Versi aman: 1.106.2, 1.107.0rc1, dan 1.107.0rc2. Rilis 1.107.0 sudah ditarik dari PyPI.

Apa yang dilakukan malware di LiteLLM 1.107.0?

Tiga file dipasang ke site-packages: cook.pth, cook.py, dan sitecustomize.py. Dua di antaranya dimuat setiap kali Python start, dan semuanya berjalan tanpa perlu ada kode yang mengimpor litellm.

cook.pth berisi 12 byte dengan isi satu baris impor yang memuat cook.py. File cook.py berukuran 22.252 byte dan isinya payload terkompresi yang dieksekusi saat runtime. Tugasnya mengumpulkan kredensial: kunci SSH, kredensial cloud, secret CI/CD, token tool AI, password yang tersimpan di browser, dan kunci provider LLM yang tersimpan di database LiteLLM proxy. Data yang terkumpul dienkripsi lalu dikirim ke www.litellm.dev, domain yang meniru nama proyek.

File ketiga, sitecustomize.py berukuran 25.509 byte, berperan sebagai loader sekaligus backdoor dengan stealer tertanam. Setiap jam daemon-nya membaca alamat server dari sebuah file di GitHub, menjalankan stealer lagi, lalu mengunduh dan mengeksekusi kode dari server tersebut. Pola ini membuat pembersihan sederhana tidak cukup: menghapus satu file belum tentu mematikan jalur unduh ulangnya.

Versi LiteLLM mana yang aman?

1.106.2, 1.107.0rc1, dan 1.107.0rc2 dinyatakan bersih. Dua paket pendamping yang dipin oleh 1.107.0, yaitu litellm-proxy-extras versi 0.4.110 dan litellm-enterprise versi 0.1.78, juga bersih.

Yang penting dicatat: paket pendamping itu bersih, tapi rilis induk yang memintanya tetap berbahaya. Jadi menemukan versi pendamping yang benar di lockfile bukan bukti bahwa instalasi aman. Yang menentukan adalah versi litellm itu sendiri.

VersiStatusTindakan
1.107.0Berbahaya, sudah ditarik dari PyPIAnggap host sudah kompromi bila pernah terpasang
1.107.0rc1BersihAman dipakai sebagai versi uji
1.107.0rc2BersihAman dipakai sebagai versi uji
1.106.2BersihPilihan paling aman untuk produksi saat ini

Bagaimana implant bisa masuk ke rilis resmi?

Lewat satu baris tambahan di pyproject.toml pada source distribution. Di bagian build maturin ada penambahan data = "cook", yang membuat maturin menyalin folder cook ke dalam wheel sehingga pip memasangnya ke site-packages.

Yang membuatnya sulit terlihat: sdist tidak menyertakan folder cook itu sendiri, sehingga satu baris tersebut adalah satu-satunya perubahan yang tampak. Tidak ada commit publik di repositori BerriAI/litellm yang memuat baris data = "cook" atau folder cook. Artinya perubahan ini tidak berasal dari riwayat git yang bisa diaudit publik.

Ada juga ketidakcocokan antara tag dan isi rilis. Tag v1.107.0 menunjuk ke commit 66c8f5b pada 06:59 UTC, sementara pyproject.toml di sdist menyebut version = "1.108.0". SafeDep membandingkan setiap file sdist dengan tree git berdasarkan hash blob, dan hasilnya sdist cocok dengan commit main yang lebih baru, a8113b0 pada 08:50 UTC, ditambah lima file yang diedit dan folder cook. Empat dari lima file yang diedit adalah Cargo.toml yang mendapat baris readme, dan editan serupa juga ada di rilis sah 1.106.2 serta rc2. File kelima adalah pyproject.toml, yang memuat penurunan versi, perubahan pin paket pendamping, dan baris injeksi data = "cook".

Catatan teknis lengkapnya ada di analisis SafeDep, termasuk perbandingan RECORD wheel yang mencantumkan ketiga file tambahan beserta ukurannya.

Bagaimana memeriksa apakah sebuah sistem terdampak?

Periksa isi site-packages untuk ketiga nama file, lalu periksa versi litellm yang benar-benar terpasang, bukan yang tertulis di requirements.

Langkah pertama, cek versi yang terpasang lewat manajer paket Python yang dipakai. Langkah kedua, cari keberadaan cook.pth, cook.py, dan sitecustomize.py di direktori site-packages lingkungan virtual yang bersangkutan. sitecustomize.py adalah nama yang juga dipakai paket sah lain, jadi keberadaannya saja bukan bukti, tapi keberadaan bersama cook.pth dengan ukuran 12 byte adalah sinyal kuat. Langkah ketiga, periksa log koneksi keluar ke domain www.litellm.dev. Koneksi ke domain itu dari host yang menjalankan LiteLLM bukan lalu lintas normal.

Karena stealer menyasar kredensial cloud dan kunci provider LLM, host yang terbukti terdampak harus dianggap seluruh kredensial yang pernah ada di sana sudah bocor. Ini termasuk kunci yang tidak dipakai oleh LiteLLM sendiri, karena stealer berjalan di level proses Python dan membaca dari sistem, bukan dari konfigurasi aplikasi.

Apa yang harus dilakukan kalau sudah terpasang?

Urutannya: putus host dari jaringan, hapus ketiga file, turunkan versi ke 1.106.2, lalu rotasi semua kredensial yang pernah ada di host tersebut.

Menghapus file tanpa memutus jaringan hanya memberi daemon kesempatan memuat ulang payload. Karena daemon membaca alamat server dari file GitHub dan berjalan tiap jam, pembersihan harus dilakukan pada host yang sudah terisolasi. Setelah bersih, rotasi kredensial adalah bagian yang tidak bisa dilewati: kunci SSH, token cloud, secret CI/CD, token provider LLM, dan password yang tersimpan di browser pada host itu semuanya masuk kategori yang dikumpulkan stealer.

Untuk pemulihan paket, pin versi secara eksplisit di requirements atau lockfile dan gunakan pemeriksaan hash. Dokumentasi pip install menjelaskan opsi hash-checking mode yang membuat pip menolak paket yang hash-nya tidak cocok dengan yang tercatat. Halaman paket litellm di PyPI bisa dipakai untuk memastikan versi yang hendak dipasang memang masih tersedia resmi, dan riwayat rilis di repositori BerriAI/litellm membantu membandingkan tag dengan isi rilis.

Bagaimana mencegah kejadian serupa terulang?

Tiga langkah yang paling berdampak: kunci versi dengan hash, batasi kredensial yang bisa dijangkau proses build, dan pisahkan lingkungan instalasi dari host yang menyimpan kredensial produksi.

Serangan ini berhasil karena rantai pasok dipakai sebagai jalur masuk. Instalasi yang mengunci versi plus hash akan menolak paket yang isinya berubah, meski nomor versinya sama. Setelah itu, kurangi nilai yang bisa dicuri: proses build dan CI sebaiknya tidak memegang kunci produksi, dan kredensial yang dipakai di sana diberi masa berlaku pendek.

Yang juga perlu diubah adalah kebiasaan memasang paket langsung di host yang menyimpan kunci SSH dan kredensial cloud. Lingkungan terpisah, misalnya container sekali pakai untuk build, membuat stealer yang berhasil masuk tidak menemukan apa pun yang berharga. Untuk proyek yang memakai LiteLLM sebagai gateway ke banyak provider, kunci provider justru terkumpul di satu tempat, sehingga nilai targetnya tinggi dan lapisan pemisahan jadi lebih penting.

Kenapa nama domain penampungnya meniru nama proyek?

Karena www.litellm.dev terlihat seperti domain resmi proyek, sehingga koneksi keluar ke alamat itu tidak langsung mencurigakan saat dilihat sekilas di log.

Ini pilihan yang disengaja. Kalau stealer mengirim data ke domain acak, pemeriksaan log sederhana akan langsung menemukannya. Dengan nama yang menyerupai proyek asli, lalu lintas itu bisa lolos dari pandangan pertama, terutama di lingkungan yang punya banyak koneksi keluar ke berbagai layanan. Karena itu, pencarian di log sebaiknya dilakukan dengan mencocokkan nama domain persis, bukan mengandalkan kesan visual.

Apakah paket lain di lingkungan yang sama ikut berisiko?

Ya, dalam arti tertentu. Stealer berjalan di level proses Python, jadi kredensial yang dikumpulkan tidak terbatas pada milik LiteLLM. Kunci SSH, kredensial cloud, dan token tool lain di host yang sama semuanya masuk jangkauan.

Ini yang membuat dampaknya lebih luas daripada satu paket. Sebuah host yang hanya memakai LiteLLM sebagai gateway tetap bisa kehilangan kunci yang sama sekali tidak berkaitan dengan LiteLLM, misalnya kredensial deploy atau token repositori. Karena itu, setelah pembersihan, rotasi kredensial harus mencakup seluruh kredensial yang pernah ada di host tersebut, bukan hanya kunci provider LLM.

Apakah menarik rilis dari PyPI sudah cukup?

Untuk pemakaian baru, cukup. Tapi penarikan tidak menghapus instalasi yang sudah terjadi, dan tidak membersihkan cache atau mirror internal yang mungkin sudah menyimpan wheel tersebut.

Karena itu, setelah sebuah rilis berbahaya ditarik, langkah berikutnya adalah menyisir lingkungan yang ada: lingkungan virtual di server, cache pip di mesin pengembang, dan mirror paket internal. Mirror internal sering terlewat karena dianggap tepercaya, padahal isinya adalah salinan dari sumber yang sama. Selama salinan itu masih ada, instalasi baru dari mirror tetap memasang payload yang sama.

Apakah LiteLLM masih layak dipakai setelah insiden ini?

Insiden ini terjadi di jalur distribusi, bukan pada desain LiteLLM sebagai gateway. Versi 1.106.2 dan dua release candidate 1.107.0 dinyatakan bersih, sehingga secara teknis masih bisa dipakai dengan pin versi yang ketat dan pemeriksaan hash.

Yang berubah adalah cara memasangnya. Memasang tanpa pin versi dan tanpa pemeriksaan hash bukan lagi kebiasaan yang bisa dipertahankan, karena kejadian ini menunjukkan bahwa rilis resmi di indeks paket publik bisa tercemar meski kode sumbernya bersih.

FAQ

Apakah LiteLLM 1.107.0 masih bisa diunduh dari PyPI?

Tidak. PyPI sudah menghapus rilis tersebut setelah temuan dipublikasikan. Kalau sebuah mirror internal masih menyimpannya, hapus dari mirror itu dan jangan pasang dari cache lama.

Apakah paket litellm-proxy-extras dan litellm-enterprise ikut tercemar?

Tidak. Keduanya dinyatakan bersih pada versi yang dipin oleh 1.107.0, yaitu 0.4.110 dan 0.1.78. Pencemaran terjadi di paket litellm induk lewat file tambahan di wheel.

Apakah cukup menghapus cook.py untuk membersihkan sistem?

Tidak cukup. Ada tiga file yang terpasang, dan sitecustomize.py menjalankan daemon yang bisa memuat ulang payload. Isolasi host lalu rotasi kredensial tetap diperlukan meski file sudah dihapus.

Kenapa malware bisa berjalan tanpa kode yang mengimpor litellm?

Karena dua file dimuat otomatis oleh mekanisme start Python. cook.pth diproses saat inisialisasi path, dan sitecustomize.py diimpor saat interpreter start, jadi keduanya aktif tanpa perlu ada baris impor di kode aplikasi.

💬 Komentar (0)

Belum ada komentar. Jadilah yang pertama! 💬

Komentar akan muncul setelah moderasi.