Apa yang terjadi pada 21 Oktober
Selasa lalu, pipeline rilis milik LiteLLM sendiri menerbitkan versi 1.107.0 ke PyPI dan ke registry container-nya, dan versi itu mencuri kredensial. Menurut laporan insiden resminya (kutipan di artikel ini kami terjemahkan dari bahasa Inggris), "pipeline rilis LiteLLM disusupi dan mendorong v1.107.0 ke registry docker dan PyPI", dan rilis itu "berisi malware terkompilasi yang mencuri kredensial dan memuat perkakas eksekusi kode jarak jauh". LiteLLM menyebut insiden ini sudah terkendali. Investigasinya masih berjalan saat laporan terakhir diperbarui, pukul 20.30 UTC tanggal 21 Oktober.
Kasus ini lebih serius daripada typosquat biasa. Tidak ada yang perlu dikelabui agar memasang paket tiruan. Nama paket yang asli, pipeline yang asli, dan langkah penandatanganan yang asli semuanya mengantarkan kode penyerang. Kalau tim Anda memakai LiteLLM sebagai gateway model, gateway itu kemungkinan besar menyimpan semua API key penyedia model yang Anda punya. Perlakukan ini sebagai insiden rahasia lebih dulu, baru insiden dependensi.
Ini juga kompromi rantai pasok kedua yang menimpa LiteLLM tahun ini. The Hacker News melaporkan bahwa teknik peluncuran lewat .pth yang sama muncul pada kompromi versi 1.82.7 dan 1.82.8 di bulan Maret 2026.
Bagaimana provenance bertanda tangan menandatangani kode yang salah
Laporan LiteLLM menjabarkan akar masalahnya. Penyerang memegang kredensial GitHub CLI milik tiga developer. Salah satunya milik seorang owner organisasi, dan penyerang memakainya untuk menembus branch protection serta mengubah workflow rilis privat. Kredensial developer kedua dipakai untuk meloloskan tahap persetujuan. Workflow itu lalu membangun, menandatangani, dan menerbitkan artefak dari repositori tiruan, Berri-AI/litellm, dengan tanda hubung. Organisasi yang asli bernama BerriAI.
Analisis StepSecurity menambahkan detail yang patut dicermati. Tag git v1.107.0 sendiri bersih. Penyerang menumpuk sepuluh commit di atasnya di repo tiruan, termasuk baris data = "cook" di pyproject.toml. Ketujuh wheel, yang mencakup macOS, manylinux, musllinux, dan Windows, semuanya disusupi backdoor.
Inilah poin yang terus diangkat di thread Hacker News. Attestation membuktikan workflow mana yang menerbitkan sebuah paket. Ia tidak membuktikan dari sumber mana workflow itu membangun. Begitu seseorang dengan hak owner bisa mengedit workflow, tanda tangan itu hanya menunjukkan bahwa build berasal dari pipeline resmi, dan itu memang benar. Tanda tangan itu sama sekali tidak bicara soal kodenya.
Bagaimana token-token itu bocor? Bagian ini adalah versi LiteLLM dan belum dipastikan secara independen. Laporannya menyebut bahwa dalam situasi tertentu "Claude Code akan menyisipkan token OAuth GitHub CLI milik pengguna ke dalam body respons". Menurut LiteLLM, body respons itu tercatat di log sebuah deployment LiteLLM internal yang terbuka ke internet publik. LiteLLM menduga akses awal didapat lewat kerentanan yang baru saja ditambal, tetapi belum mengonfirmasinya. Apa pun temuan akhirnya, pola rantainya sudah cukup jelas untuk ditindaklanjuti: kredensial milik agen coding AI berakhir di log request sebuah gateway AI, dan log itu bisa dijangkau dari luar.
Apa yang dilakukan payload-nya
Tulisan SafeDep menjelaskan kenapa ini lebih buruk daripada import berbahaya biasa. Wheel-wheel itu menaruh file cook.pth berukuran 12 byte yang berisi import cook. Python menjalankan file .pth saat interpreter dinyalakan, jadi pencuri ini berjalan di setiap proses Python di host tersebut, termasuk proses yang tidak pernah mengimpor litellm. Sebuah sitecustomize.py memunculkan daemon yang terlepas dari proses induknya. Setiap jam, daemon itu membaca sebuah domain dari dead drop di GitHub (letters9813/pythonclient-test), mengambil /codepy dari domain itu, lalu menjalankannya dengan exec().
Daftar yang dikumpulkannya luas:
- kunci SSH, GPG, dan TLS
- kredensial AWS, Azure, dan gcloud, kubeconfig, serta konfigurasi Docker
- secret CI untuk runner GitLab, Jenkins, Vault, dan Terraform
- kata sandi yang tersimpan di browser
- environment proses lain, dibaca dari
/proc/[pid]/environ - token perkakas coding AI, termasuk Claude Code, Cursor, Copilot, Gemini CLI, dan Codex
- dump tabel
LiteLLM_CredentialsTablemilik proxy, yang menyimpan API key penyedia model
Data itu dienkripsi lalu dikirim lewat POST ke www.litellm[.]dev/healthcheck.
Penyerang sudah memakai hasil curiannya. Wiz mengamati panggilan sts:GetCallerIdentity yang disusul pendataan model Bedrock, yang menurut Wiz "konsisten dengan LLMjacking". Di sebagian lingkungan, Wiz juga melihat enumerasi IAM dan CloudTrail.
Cek paparan dalam lima menit
Instruksi pertama LiteLLM terasa berlawanan dengan naluri: jangan mulai dengan pip install. Menjalankan Python akan memicu malware itu lagi, begitu juga perkakas apa pun yang berjalan di atas Python, termasuk pip. Lakukan pemeriksaan pertama dari shell.
Mulailah dari file-file yang ditaruh wheel itu di site-packages:
sudo find / -xdev \( -name 'cook.pth' -o -name 'cook.py' -o -name 'sitecustomize.py' \) 2>/dev/null
Lalu cari indikator host dari Wiz dan LiteLLM: file penanda, file lock milik daemon, dan proses apa pun yang membawa variabel environment pencuri itu:
ls -la /tmp/.pc_once_72129118c59f5636c0bb /tmp/remote_code_loader.lock 2>/dev/null
sudo grep -l 'PRIVCOLLECT_ACTIVE=1' /proc/*/environ 2>/dev/null
Di sebagian sistem, sitecustomize.py bisa saja sah, jadi buka dulu setiap temuan sebelum menghapusnya. Kalau ada cook.pth, file itu jelas tidak sah.
Berikutnya, periksa container. Tag yang terdampak adalah v1.107.0, latest, main-latest, dan main-stable pada image litellm, litellm-database, dan litellm-non_root. Kalau Anda menarik salah satu tag mengambang itu pada 21 Oktober, bandingkan digest yang sedang berjalan dengan digest yang Anda pakai sebelumnya:
docker image ls --digests | grep -i litellm
Setelah itu, periksa rentang waktunya. Menurut lini masa LiteLLM (semua dalam UTC, 21 Oktober), branch protection ditembus pukul 10.08. Tujuh wheel berbahaya masuk ke PyPI pukul 11.39–11.40, lalu image container menyusul pukul 11.46. PyPI sudah menghapus rilis itu pukul 13.23. Tag GHCR dipastikan tidak tersedia lagi pukul 13.51, dan tag Docker Hub dihapus atau diarahkan ulang paling lambat pukul 14.20. Setiap instalasi tanpa pin, build CI, atau penarikan image antara pukul 11.39 dan 14.20 UTC bisa saja mengambil versi yang buruk itu. Telusuri log CI dan diff lockfile Anda untuk 1.107.0 di rentang tersebut.
Kalau Anda menemukannya, aturan LiteLLM tegas: "Jika 1.107.0 pernah terpasang di host yang punya akses internet keluar, anggap eksfiltrasinya berhasil."
Bersihkan dan rotasi
Dari shell, langkah pemulihan versi LiteLLM adalah:
- Hapus
cook.pth,cook.py, dansitecustomize.py, beserta file.pyc-nya. - Matikan daemon yang memegang
/tmp/remote_code_loader.lock. - Bangun ulang dengan pin ke versi 1.106.2.
- Rotasi IAM role, setiap key penyedia di database proxy, master key dan virtual key, serta kata sandi
DATABASE_URL. - Tinjau CloudTrail untuk panggilan
GetCallerIdentity.
Di daftar rotasi inilah peran gateway terlihat. Proxy LiteLLM bukan satu secret. Ia adalah gantungan kunci untuk semua akun penyedia model yang Anda pakai, ditambah virtual key yang Anda bagikan ke tim-tim internal. Pencuri itu langsung men-dump tabelnya. Rotasi setiap barisnya, bukan hanya key yang Anda ingat pernah ditambahkan.
Untuk hal lain di host itu, lampaui daftar LiteLLM. Pencuri ini juga membaca kredensial cloud, kubeconfig, secret CI, kunci SSH, dan token agen coding. Di laptop developer atau runner build bersama, itu berarti hampir semua yang bisa dijangkau mesin tersebut.
Pihak LiteLLM juga sudah bergerak. Direktur keamanan Oliver Jensen mengatakan kepada The Hacker News bahwa "semua token yang terlibat dalam serangan ini telah dicabut." Sebagai langkah darurat, perusahaan itu mengeluarkan semua anggota organisasi GitHub-nya kecuali satu pengguna yang tidak terdampak.
Perlakukan gateway seperti brankas
Pelajaran strukturalnya menyangkut tempat menumpuknya secret. Gateway LLM memusatkan semua kredensial model yang dimiliki sebuah tim, dan secara desain ia melihat setiap request dan respons. Artinya, gateway itu adalah brankas secret, entah Anda merencanakannya begitu atau tidak. Ini yang akan saya ubah minggu ini:
- Pin berdasarkan versi dan digest. Pin dependensi Python dengan hash dan image container dengan digest
@sha256:, bukan denganlatestataumain-stable. Tag mengambang sama saja dengan undangan terbuka bagi apa pun yang terakhir diterbitkan pipeline. Perdebatan di HN soal masa tunggu 24–48 jam layak dilakukan. Dalam kasus ini PyPI sudah menarik rilisnya dalam waktu kurang dari dua jam, tetapi masa tunggu hanya berguna kalau ada yang benar-benar menyadari rilis buruk itu di dalam jendela waktunya. - Bersihkan log gateway. Kalau gateway Anda mencatat body request dan respons, sensor kredensial sebelum tertulis ke disk, atau matikan pencatatan body. Menurut versi LiteLLM, seluruh rantai ini berawal dari token yang tersimpan di body respons yang tercatat di log.
- Jaga gateway internal tetap internal. UI admin atau penyimpanan log yang terbuka ke internet publik adalah permukaan serangan yang menyimpan semua key Anda. Taruh di balik VPN atau identity-aware proxy.
- Batasi apa yang bisa dilihat agen. Ajukan pertanyaan yang diajukan thread HN: kenapa agen coding punya token GitHub di konteksnya sejak awal? Beri agen token fine-grained dengan cakupan minimum, dan jangan biarkan sesi
ghmilik owner organisasi menjadi tempat agen bekerja. - Awasi workflow rilis, bukan hanya kodenya. Di kasus ini, branch protection dan tahap persetujuan sama-sama tumbang oleh kredensial curian. Pasang alert untuk setiap perubahan aturan branch protection atau workflow rilis, supaya penembusan seperti yang terjadi pukul 10.08 menimbulkan alarm, bukan berlalu diam-diam.
Penandatanganan tetap berguna. Hanya saja, ia menjawab pertanyaan yang lebih sempit daripada yang selama ini kita kira. Sisa jawabannya datang dari memperlakukan gateway model sebagai layanan paling sensitif di stack Anda, karena bagi banyak tim, sekarang memang itulah kenyataannya.




Komentar (0)
Belum ada komentar. Mulai percakapannya.