4 poin oleh GN⁺ 2025-12-15 | 3 komentar | Bagikan ke WhatsApp
  • 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-cache dan 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.js dijalankan, ia menginstal runtime Bun dan mengeksekusi bun_environment.js di 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=true dan 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

 
click 2025-12-15

Sepertinya karena secara default pnpm memang memiliki struktur yang mengharuskan post-install diizinkan satu per satu, pada akhirnya para developer juga tanpa sadar jadi mengizinkannya.

 
lamanus 2025-12-16

Saya memahami bahwa karena npm berjalan secara default, mereka beralih ke pnpm dan menonaktifkan default tersebut untuk memperkuat keamanan.

 
GN⁺ 2025-12-15
Pendapat Hacker News
  • Menjalankan npm install bukanlah kelalaian
    Masalahnya 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

    • Menurut saya keduanya sama-sama masalah
      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
    • Logika seperti ini terlalu sirkular
      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
    • Hal yang sama juga berlaku untuk plugin IDE
      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
    • Saya penasaran bagaimana package manager yang mencegah eksekusi kode pihak ketiga bisa dirancang
      Pada akhirnya bukankah strukturnya tetap mengharuskan kita menjalankan kode yang mau tak mau harus dipercaya?
    • Beberapa alat hanya mendukung file netrc untuk autentikasi HTTP
      Jika 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

    • Meski begitu, masalah yang sama tetap terulang
      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

    • Jika ada log akses ke resource AWS dan tidak ada jejak akses sebelum haknya dicabut, data bisa dianggap aman
  • Setelah malware dijalankan, melacak asal-usulnya hampir mustahil
    pnpm install juga selesai dengan normal sehingga sulit dideteksi
    Kalau ada EDR seperti Sentinel One atau CrowdStrike, kemungkinan akan ada lebih banyak petunjuk untuk investigasi

    • Jika ada EDR, kemungkinan besar rantai serangan Trufflehog bisa terdeteksi atau diblokir
  • Bagian “total 669 repo di-clone” cukup mencolok
    Saya penasaran apakah wajar perusahaan dengan kurang dari 100 karyawan memiliki lebih dari 600 repo

    • Sepenuhnya wajar. repo itu ternak, bukan hewan peliharaan
    • Organisasi kami beranggotakan 7 orang, tetapi punya 365 repo di GitHub
      Jumlah repo lebih dipengaruhi oleh umur organisasi dan umur proyek daripada ukuran tim
    • Hasil seperti ini muncul kalau ada arsitek yang suka microservices
  • pnpm sebenarnya sudah menghentikan eksekusi otomatis lifecycle script seperti preinstall, jadi sepertinya mereka memakai versi lama
    Lihat PR terkait

    • Di akhir artikel disebutkan bahwa mereka sudah meng-update ke major version terbaru
    • Saya kira itulah alasan utama memakai pnpm, jadi agak membingungkan
    • Kalau pada akhirnya mereka memperbarui dependensi dengan package manager versi lama, maka ini tanggung jawab mereka
    • Bisa jadi proyeknya sendiri memiliki skrip postinstall
      pnpm 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 install jadi gagal

    • Fitur IP allow list milik GitHub Organization sepertinya akan membantu mencegah serangan seperti ini
  • Saya 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

    • Saya merekomendasikan konfigurasi yang memakai 1Password untuk mengelola SSH key dan penandatanganan Git, lalu push/pull lewat GitHub OAuth atau login CLI
      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
    • Saya menyimpan private SSH key di TPM lalu memakainya dari SSH agent lewat PKCS11
      Keuntungannya, key tidak bisa bocor ke luar, tetapi kalau malware berjalan di mesin saya tetap saja berbahaya
      Contoh Linux, contoh macOS
    • Kalau laptop sudah terinfeksi, tidak ada pertahanan yang benar-benar efektif
      TPM atau Yubikey bisa membuat serangan sedikit lebih sulit, tetapi tidak bisa memberi perlindungan sempurna
      Pekerjaan admin sebaiknya dilakukan di mesin khusus yang terpisah
    • Ada juga cara menaruh GPG key di Yubikey lalu memakai autentikasi SSH lewat gpg-agent
      Saat push atau commit, kunci dibuka dengan memasukkan PIN
    • Jika push langsung ke branch main diblokir dan MFA diwajibkan, penyerang akan lebih sulit langsung mengakses branch deployment
  • Commit 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