Insiden Shai-Hulud yang Menginfeksi Mesin Developer dan Mencuri Akses Organisasi GitHub: Analisis Pasca Insiden
(trigger.dev)- Paket npm berbahaya Shai-Hulud 2.0 menginfeksi mesin developer dan mencuri akses organisasi GitHub milik Trigger.dev
- Infeksi dimulai saat developer menjalankan
pnpm install, yang mengeksekusi skrip preinstall dari paket berbahaya dan mencuri kredensial menggunakan alat TruffleHog - Selama 17 jam, penyerang mengkloning 669 repositori, lalu dalam 10 menit mencoba force-push ke 199 branch dan menutup 42 PR
- Paket dan sistem produksi tidak terdampak, dan serangan terdeteksi dalam 4 menit sehingga akses akun segera diblokir
- Setelah insiden, pengamanan diperkuat dengan menonaktifkan skrip npm, upgrade ke pnpm 10, publikasi npm berbasis OIDC, dan penerapan perlindungan branch secara menyeluruh
Gambaran serangan
- Pada 25 November 2025, saat debugging internal di Slack, muncul anomali berupa commit “init” atas nama Linus Torvalds di beberapa repositori
- Hasil investigasi menunjukkan worm supply chain Shai-Hulud 2.0 telah menginfeksi mesin developer dan mencuri kredensial GitHub
- Worm ini dilaporkan telah menginfeksi lebih dari 500 paket npm dan berdampak pada lebih dari 25.000 repositori
- Paket npm resmi Trigger.dev (
@trigger.dev/*, CLI) tidak terinfeksi
Timeline serangan
- 24 November 04:11 UTC: distribusi paket berbahaya dimulai
- 20:27 UTC: mesin developer di Jerman terinfeksi
- 22:36 UTC: akses pertama penyerang dan dimulainya kloning massal repositori
- 15:27~15:37 UTC (25 November): serangan destruktif dilakukan selama 10 menit
- 15:32 UTC: anomali terdeteksi dan akses diblokir dalam 4 menit
- 22:35 UTC: pemulihan semua branch selesai
Proses infeksi
- Saat developer menjalankan
pnpm install, skrip preinstall dari paket berbahaya dijalankan, mengunduh dan mengeksekusi TruffleHog - TruffleHog memindai lalu mengekfiltrasi token GitHub, kredensial AWS, token npm, variabel environment, dan lainnya
- Pada mesin yang terinfeksi ditemukan direktori
.trufflehog-cachedan file terkait - Paket yang menjadi sumber infeksi telah dihapus sehingga tidak bisa lagi dilacak
Aktivitas penyerang
- Setelah infeksi, penyerang melakukan aktivitas reconnaissance selama 17 jam
- Menggunakan infrastruktur berbasis AS dan India untuk mengkloning 669 repositori
- Memantau aktivitas developer sambil mempertahankan akses melalui token GitHub
- Membuat repositori bernama “Sha1-Hulud: The Second Coming”, yang diduga digunakan untuk menyimpan kredensial
- Setelah itu, selama 10 menit dilakukan aksi destruktif
- Mencoba force-push ke 199 branch di 16 repositori
- Menutup 42 PR, sebagian diblokir oleh pengaturan perlindungan branch
- Semua commit ditampilkan dalam format “Linus Torvalds <email> / init”
Deteksi dan respons
- Anomali terdeteksi secara real-time melalui notifikasi Slack
- Dalam 4 menit, akses GitHub untuk akun yang terinfeksi diblokir, lalu seluruh akses layanan seperti AWS, Vercel, dan Cloudflare juga dicabut
- Analisis log AWS CloudTrail menunjukkan hanya ada panggilan API read-only, tanpa akses ke data produksi
- AWS juga secara terpisah mendeteksi aktivitas mencurigakan terkait Shai-Hulud dan mengirimkan peringatan
Dampak dan pemulihan
- 669 repositori dikloning, 199 branch di-force-push, 42 PR ditutup
- Pemulihan sulit dilakukan karena GitHub tidak memiliki reflog sisi server, namun dengan memanfaatkan Event API dan reflog lokal, semuanya berhasil dipulihkan dalam 7 jam
- Paket npm dan infrastruktur produksi tidak mengalami kerusakan
Kebocoran kunci GitHub App
- Selama investigasi, private key GitHub App ditemukan di trash laptop developer
- Kunci tersebut memiliki izin read/write ke repositori pelanggan dan segera dirotasi
- Database (penyimpanan installation ID) tidak terdampak sehingga tidak ada bukti akses ke repositori pelanggan, namun kemungkinan itu tidak bisa sepenuhnya dikesampingkan
- Tim meminta log tambahan ke dukungan GitHub dan mengirim pemberitahuan email ke pelanggan
Analisis teknis Shai-Hulud
- Saat
setup_bun.jsdijalankan, ia menginstal runtime Bun dan mengeksekusibun_environment.jsdi background - TruffleHog digunakan untuk mengumpulkan kredensial di direktori
$HOME - Data yang dikumpulkan (
contents.json,cloud.json,truffleSecrets.json, dan lainnya) diunggah ke repositori GitHub acak dalam bentuk triple base64-encoded - Jika ada token npm, worm akan memodifikasi dan memublikasikan ulang paket milik akun yang terinfeksi untuk memperluas penyebaran
- Jika tidak ada kredensial, worm mencoba menghapus direktori home
- File indikator infeksi:
setup_bun.js,bun_environment.js,.trufflehog-cache/, dan lainnya
Langkah penguatan keamanan
- Menonaktifkan seluruh skrip npm (
ignore-scripts=true) - Upgrade ke pnpm 10: skrip dinonaktifkan secara default, dan
minimumReleaseAge(3 hari) diatur untuk menunda instalasi paket baru - Mengadopsi npm Trusted Publishers berbasis OIDC untuk menghapus token jangka panjang
- Menerapkan perlindungan branch di semua repositori
- Mengadopsi Granted untuk AWS SSO, dengan enkripsi token sesi
- Di GitHub Actions, workflow dari kontributor eksternal kini wajib mendapat persetujuan sebelum dijalankan
Pelajaran untuk tim lain
- Struktur eksekusi kode arbitrer saat instalasi npm itu sendiri merupakan permukaan serangan
- Perlu mengaktifkan
ignore-scripts=truedan mengelola whitelist hanya untuk paket yang benar-benar diperlukan - Gunakan pnpm minimumReleaseAge untuk menunda instalasi paket baru
- Perlindungan branch dan deployment berbasis OIDC adalah langkah keamanan yang wajib
- Jangan menyimpan kredensial jangka panjang di mesin lokal; izinkan deployment hanya melalui CI
- Noise dari notifikasi Slack menjadi kunci deteksi
Sisi manusiawi
- Developer yang terinfeksi tidak bersalah; insiden terjadi hanya karena menjalankan
npm install - Selama serangan, ditemukan jejak bahwa akun tersebut otomatis memberi ‘star’ ke ratusan repositori acak
- Insiden ini menunjukkan kerentanan struktural dalam ekosistem, bukan kesalahan individu
Metrik ringkas
- Dari infeksi awal ke serangan pertama: sekitar 2 jam
- Lama penyerang mempertahankan akses: 17 jam
- Durasi aksi destruktif: 10 menit
- Waktu ke deteksi: 5 menit, waktu ke pemblokiran: 4 menit
- Waktu hingga pemulihan penuh: 7 jam
- Repositori yang dikloning: 669 / branch terdampak: 199 / PR yang ditutup: 42
Referensi
- Socket.dev: Shai-Hulud Strikes Again V2
- Laporan analisis dari PostHog, Wiz, Endor Labs, dan HelixGuard
- Dokumentasi npm Trusted Publishers, pnpm
onlyBuiltDependencies,minimumReleaseAge, dan Granted
3 komentar
Sepertinya karena secara default
pnpmmemang memiliki struktur yang mengharuskanpost-installdiizinkan satu per satu, pada akhirnya para developer juga tanpa sadar jadi mengizinkannya.Saya memahami bahwa karena
npmberjalan secara default, mereka beralih kepnpmdan menonaktifkan default tersebut untuk memperkuat keamanan.Pendapat Hacker News
Menjalankan
npm installbukanlah kelalaianMasalahnya adalah ekosistem yang mengizinkan eksekusi kode arbitrer selama proses instalasi paket
Namun kegagalan keamanan yang lebih mendasar adalah menggunakan package manager yang memungkinkan pihak ketiga menyisipkan kode ke produk saya tanpa verifikasi apa pun
Pada akhirnya, kita bergantung tanpa batas pada niat baik dan kemampuan package manager serta para pengelolanya
Selain itu, tampaknya OP menyiratkan bahwa kredensial disimpan sebagai plaintext di filesystem
Di tingkat bahasa, dimungkinkan membuat struktur yang membatasi kode agar hanya bisa membaca input, mengonsumsi sumber daya, dan hanya menghasilkan output yang benar secara tipe
Ini memang bukan solusi lengkap untuk masalah supply chain, tetapi dapat sangat mengurangi cakupan paparan
Seperti mengatakan, “tidak salah kalau satu orang memakai alat seperti ini, tapi kalau semua orang memakainya ekosistem jadi bermasalah”
Sudah berkali-kali terbukti bahwa banyak alat developer memang rentan secara keamanan
Kalau benar-benar peduli, harus ditunjukkan lewat tindakan
Saat memakai VS Code, saya merasa tidak nyaman karena untuk menambah satu fitur kecil saja harus memasang plugin dari orang yang bahkan tidak kita kenal
Pada akhirnya bukankah strukturnya tetap mengharuskan kita menjalankan kode yang mau tak mau harus dipercaya?
netrcuntuk autentikasi HTTPJika memakai git lewat HTTP, jalur paparan kredensial plaintext seperti ini hampir selalu ada
Maintainer pnpm setahun lalu sudah mengusulkan “memblokir skrip post-install secara default”
Dari sudut pandang pengguna ini memang merepotkan, tetapi diyakini akan menjadi perubahan yang nantinya disyukuri semua orang dalam jangka panjang
PR terkait: pnpm/pnpm#8897
Pada akhirnya ini sekali lagi contoh kenyamanan mengalahkan keamanan
Mereka mengatakan “database tidak dibobol”, tetapi jika penyerang mengakses AWS dan secret, menurut saya itu sudah termasuk kebobolan
Jika ada kemungkinan akses, itu harus dianggap sebagai kompromi
Setelah malware dijalankan, melacak asal-usulnya hampir mustahil
pnpm installjuga selesai dengan normal sehingga sulit dideteksiKalau ada EDR seperti Sentinel One atau CrowdStrike, kemungkinan akan ada lebih banyak petunjuk untuk investigasi
Bagian “total 669 repo di-clone” cukup mencolok
Saya penasaran apakah wajar perusahaan dengan kurang dari 100 karyawan memiliki lebih dari 600 repo
Jumlah repo lebih dipengaruhi oleh umur organisasi dan umur proyek daripada ukuran tim
pnpm sebenarnya sudah menghentikan eksekusi otomatis lifecycle script seperti
preinstall, jadi sepertinya mereka memakai versi lamaLihat PR terkait
postinstallpnpm memblokir skrip milik dependensi, tetapi skrip level proyek tetap dijalankan
Terima kasih sudah membagikan post-mortem yang transparan
Kasus seperti ini penting bagi seluruh industri
Saya penasaran apakah traffic serangan bisa dibedakan dari traffic developer biasa
Kami juga ingin memperketat egress filtering di lingkungan dev, tetapi sering bermasalah karena
npm installjadi gagalSaya sedang memikirkan keamanan git di laptop pribadi
Saat ini saya menyimpan SSH key secara lokal untuk push
Saya juga punya hak admin, jadi terasa berisiko. Ingin tahu cara membuatnya lebih aman
Dengan begitu, kunci penandatanganan dan kunci akses bisa dipisahkan, dan akun admin bisa dikelola secara terpisah
Dokumentasi terkait: 1Password SSH Agent, Git Commit Signing, GitHub OAuth, GitHub CLI Login
Keuntungannya, key tidak bisa bocor ke luar, tetapi kalau malware berjalan di mesin saya tetap saja berbahaya
Contoh Linux, contoh macOS
TPM atau Yubikey bisa membuat serangan sedikit lebih sulit, tetapi tidak bisa memberi perlindungan sempurna
Pekerjaan admin sebaiknya dilakukan di mesin khusus yang terpisah
gpg-agentSaat push atau commit, kunci dibuka dengan memasukkan PIN
maindiblokir dan MFA diwajibkan, penyerang akan lebih sulit langsung mengakses branch deploymentCommit atas nama Torvalds adalah penanda (signature) yang sering terlihat setelah infeksi
Juga disebutkan dalam analisis resmi Microsoft
Worm ini sangat berisik, dan beberapa penyerang menyalahgunakan kredensial yang terekspos untuk membuka repo privat ke publik atau mengubah readme demi promosi
Kalau penyerang diam-diam hanya mengekfiltrasi informasi tanpa tindakan destruktif, saya ragu apakah deteksi seperti ini masih mungkin dilakukan