- Seattle Times kebetulan lolos dari serangan Shai-Hulud 2.0, tetapi dengan asumsi bahwa keberuntungan tidak bisa menjadi strategi keamanan, mereka menerapkan pertahanan sisi klien
- Peningkatan npm seperti Trusted publishing / provenance / granular tokens memperkuat sisi “publishing”, tetapi masih menyisakan celah karena tidak menghentikan eksekusi kode berbahaya saat “install/update”
- pnpm tetap menggunakan registry npm, tetapi menambahkan kontrol yang membuat eksekusi paket berbahaya lebih sulit pada tahap consuming (install/update)
- Dalam pilot, mereka menerapkan 3 kontrol pnpm yang dirancang untuk masing-masing memblokir vektor seperti eksekusi lifecycle script, instalasi langsung rilis terbaru, dan penurunan tingkat kepercayaan
- Pengecualian dipandang bukan sebagai kegagalan, melainkan bagian dari desain, dengan tujuan operasi defense-in-depth agar sambil mendokumentasikan pengecualian, lapisan lain tetap terus melindungi
Latar belakang insiden dan premis
- Pada November 2025 terjadi kasus worm npm yang dapat mereplikasi diri yang menginfeksi 796 paket dan menyebar di skala 132 juta unduhan per bulan
- Serangan memanfaatkan skrip preinstall untuk mencuri kredensial, memasang backdoor persisten, dan di beberapa lingkungan bahkan menghapus lingkungan pengembangan
- Alasan organisasi mereka tidak terdampak bukan karena pertahanan yang kuat, melainkan karena secara kebetulan tidak menjalankan
npm install/npm update selama periode serangan
- Bagi organisasi berita, kepercayaan adalah inti; pelanggaran rantai pasok dapat mengekspos data pelanggan, kredensial karyawan, infrastruktur produksi, dan source code, dengan biaya pemulihan dan notifikasi yang besar
Tim dan konteks adopsi
- Seattle Times sudah lama menggunakan npm sebagai package manager utama, dan meski pernah bereksperimen dengan Yarn, itu tidak menetap
- Alasan mengadopsi pnpm adalah karena kontrol keamanan sisi klien yang melengkapi peningkatan di level registry
- pnpm dinilai punya peluang tinggi untuk diadopsi karena merupakan drop-in replacement yang memakai registry, perintah, dan workflow yang sama
- Ini bukan studi kasus yang sudah selesai, melainkan berbagi masalah dan alur pikir yang dialami tim nyata saat baru mulai menangani keamanan rantai pasok
Mengapa kontrol sisi klien diperlukan
- Peningkatan keamanan npm memang membuat publikasi paket berbahaya setelah pembajakan akun menjadi lebih sulit
- Namun peningkatan ini melindungi sisi “publishing”, bukan mencegah instalasi paket berbahaya itu sendiri pada tahap “consuming”
- Saat
npm install/npm update, lifecycle scripts (preinstall/postinstall, dll.) dapat mengeksekusi kode arbitrer dengan hak pengembang sebelum evaluasi keamanan paket dilakukan
- Skrip tersebut dapat mengakses kredensial npm/GitHub/AWS/DB, source code, infrastruktur cloud, dan seluruh filesystem
- Serangan seperti Shai-Hulud menyalahgunakan struktur ini; jika akun maintainer dibajak, skrip berbahaya bisa berjalan pada saat instalasi sebelum komunitas sempat mendeteksinya
- Peningkatan sisi publishing dari npm + kontrol sisi consuming dari pnpm digabung sebagai pertahanan yang saling melengkapi untuk membentuk “defense-in-depth”
Tiga lapisan yang diterapkan
- Dalam pilot, tiga kontrol yang menargetkan vektor serangan berbeda digunakan bersama
- Setiap kontrol memiliki jalur keluar untuk pengecualian yang realistis, dan dirancang dengan asumsi bahwa pengecualian memang akan dibutuhkan di lingkungan nyata
Control 1: Lifecycle Script Management
- pnpm pada dasarnya dapat memblokir lifecycle scripts dan tetap melanjutkan instalasi dengan peringatan
- Karena ada kekhawatiran peringatan bisa diabaikan, mereka memilih
strictDepBuilds: true agar jika ada skrip, instalasi langsung gagal
- Contoh konfigurasinya di
pnpm-workspace.yaml terdiri dari field berikut
strictDepBuilds: true
onlyBuiltDependencies: allowlist paket yang memiliki build script yang memang diperlukan
ignoredBuiltDependencies: daftar paket yang diblokir (atau diabaikan) karena memiliki build script yang tidak diperlukan
- “Skrip yang diperlukan” didefinisikan sebagai hal seperti kompilasi ekstensi native atau penautan library yang bergantung platform
- “Skrip yang tidak diperlukan” didefinisikan sebagai optimisasi atau konfigurasi opsional yang tidak memengaruhi fungsi dalam cara tim menggunakan paket tersebut
- Kegagalan instalasi memaksa langkah berikut
- pnpm dengan jelas memberi tahu paket mana yang memiliki skrip
- Menyelidiki dan memahami perilaku skrip
- Membuat keputusan allow/block secara sadar dengan penilaian manusia dan mendokumentasikannya
- Tim pnpm sedang mempertimbangkan menjadikan
strictDepBuilds: true sebagai default di v11 dan juga meninjau perbaikan penamaan sintaks allow/deny
Control 2: Release Cooldown
- Versi yang baru dirilis diblokir dari instalasi selama periode cooldown tertentu, memberi waktu bagi komunitas untuk mendeteksi dan menghapus paket berbahaya
- Contoh konfigurasinya di
pnpm-workspace.yaml terdiri dari field berikut
minimumReleaseAge: <duration-in-minutes>
minimumReleaseAgeExclude: allowlist pengecualian seperti hotfix darurat
- Ini menuntut perubahan cara berpikir dari kebiasaan “terbaru adalah terbaik” menjadi bahwa dari perspektif rantai pasok, versi yang sedikit lebih lama bisa lebih aman
- Dalam serangan September 2025 (16 paket termasuk debug dan chalk), paket dihapus dalam sekitar 2,5 jam, sedangkan Shai-Hulud 2.0 pada November 2025 memakan waktu sekitar 12 jam
- Tergantung toleransi risiko organisasi, cooldown bisa diatur dalam jam/hari/minggu, dan dalam bentuk apa pun itu akan mencegah serangan tersebut
- Ini selaras dengan kenyataan bahwa organisasi memang tidak selalu bisa memakai yang paling baru, jadi cooldown tidak terlalu mengganggu pekerjaan
- Ketika benar-benar diperlukan, seperti patch keamanan atau bug kritis, pengecualian dapat diberikan setelah peninjauan
Control 3: Trust Policy
- Instalasi diblokir jika muncul versi yang dipublikasikan dengan autentikasi yang lebih lemah dibanding versi sebelumnya
- Mereka menjelaskan ini sebagai sinyal bahwa akun maintainer mungkin telah dibajak dan publikasi dilakukan dari mesin penyerang, bukan dari CI/CD resmi
- Contoh konfigurasinya di
pnpm-workspace.yaml terdiri dari field berikut
trustPolicy: no-downgrade
trustPolicyExclude: allowlist pengecualian seperti migrasi CI/CD
- npm dijelaskan melacak tiga tingkat kepercayaan untuk publikasi paket (kuat → lemah)
- Trusted Publisher: berbasis GitHub Actions + OIDC + npm provenance
- Provenance: attestation yang ditandatangani dari CI/CD
- No Trust Evidence: publikasi berbasis username/password atau token
- Jika versi baru memiliki tingkat kepercayaan yang lebih rendah dari versi sebelumnya, instalasi akan gagal
- Dalam serangan s1ngularity Agustus 2025, di mana penyerang memublikasikan versi berbahaya secara lokal tanpa akses ke CI/CD sehingga tidak ada provenance, kontrol ini seharusnya akan memblokir instalasi
- Contoh kasus penurunan yang sah termasuk maintainer baru bergabung, migrasi CI/CD, atau hotfix manual saat CI/CD bermasalah; setelah diselidiki, hal-hal ini ditambahkan ke daftar pengecualian
- Fitur ini adalah fitur baru yang ditambahkan ke pnpm pada November 2025, dan mereka masih mempelajari seberapa sering penurunan yang sah benar-benar terjadi
Contoh cara kombinasi lapisan bekerja: patch kerentanan React
- Dalam skenario di mana patch untuk kerentanan kritis React Server Components yang diumumkan pada Desember 2025 harus segera diterapkan
- Biasanya cooldown akan memblokir “instalasi versi yang baru saja dirilis”, tetapi untuk patch keamanan kritis mereka tidak bisa menunggu
- Dalam kasus ini, versi React tertentu ditambahkan ke
minimumReleaseAgeExclude, tetapi pengecualian hanya diterapkan setelah meninjau pengumuman kerentanan dan legitimasi patch
- Bahkan setelah pengecualian diterapkan, lapisan lain tetap melindungi
- React umumnya tidak memiliki lifecycle scripts, jadi jika versi patch tiba-tiba menambahkan skrip, itu akan menjadi sinyal mencurigakan dan bisa diblokir
- Jika penyerang mencuri kredensial dan memublikasikan “patch” secara lokal, itu bisa diblokir karena penurunan tingkat kepercayaan
- Pengecualian diposisikan bukan sebagai “kegagalan keamanan”, melainkan desain di mana meski satu lapisan dilewati, lapisan lain tetap ada sehingga single point of failure hilang
Hasil penerapan pilot
- Mereka menjalankan PoC dengan menerapkan ketiga kontrol pada satu layanan backend
- Total waktu persiapan untuk investigasi, pemahaman, dan definisi pendekatan hanya beberapa jam
- pnpm mengidentifikasi tiga paket yang memiliki lifecycle scripts
- esbuild: mengoptimalkan startup CLI hingga level milidetik, tetapi tim hanya memakai JS API sehingga dianggap tidak perlu
- @firebase/util: konfigurasi otomatis client SDK, tetapi tim hanya memakai server SDK sehingga dianggap tidak perlu
- protobufjs: pemeriksaan kompatibilitas skema, tetapi hanya digunakan sebagai dependensi transitif dan dianggap tidak perlu dalam use case tim
- Setelah meninjau dokumentasi dan menganalisis skrip (termasuk bantuan AI untuk menginterpretasikan skrip), mereka menyimpulkan ketiga skrip itu tidak diperlukan untuk use case tim dan memblokir semuanya
- Tidak ada dampak fungsional
- Friction adalah fitur yang disengaja: mekanisme pemaksa agar tim tidak lagi secara implisit mempercayai kode yang berjalan di lingkungan mereka
- Jika dependensi baru memiliki skrip, mereka memperkirakan peninjauan dan dokumentasinya akan memakan waktu sekitar 15 menit
Pelajaran selama operasional
- Mereka merasakan kombinasi lapisan sisi klien + peningkatan sisi publishing dari npm benar-benar membuat defense-in-depth bekerja dalam praktik
- Bahkan saat pengecualian diterapkan, lapisan lain tetap ada sehingga kekhawatiran terhadap pengecualian berkurang
- Diperlukan waktu untuk beralih dari mental model “kenyamanan dulu” ke “keamanan dulu”, tetapi setelah terbiasa itu terasa alami
- Pendekatan ini praktis diterapkan bahkan di organisasi menengah tanpa tim keamanan khusus
- trust policy baru beberapa minggu tersedia, jadi mereka masih perlu mempelajari frekuensi penurunan yang sah dan rasa operasionalnya
- Mereka berencana memperluasnya ke codebase lain dalam waktu dekat, dan akan mengumpulkan lebih banyak data dari aplikasi dengan graph dependensi yang berbeda
Tips penerapan untuk tim lain
- Disarankan memulai dari satu proyek lebih dulu untuk mempelajari workflow dan titik-titik friction
- Pada lifecycle scripts, release cooldown, dan trust downgrade, pengecualian mungkin dibutuhkan, jadi rancang dengan asumsi pengecualian sejak awal
- Disarankan memakai
strictDepBuilds: true sejak hari pertama agar enforcement terjadi lewat kegagalan instalasi, bukan sekadar peringatan
- Dokumentasikan semua pengecualian agar ada jejak audit dan lebih mudah dirapikan di kemudian hari
- Ingat bahwa pengecualian pada satu lapisan tetap menyisakan perlindungan dari lapisan lain
Belum ada komentar.