Kamu bisa punya lockfile rapi, SBOM lengkap, bahkan image container minimal. Namun tetap saja, kode berbahaya bisa jalan sebelum aplikasi-mu pernah start. Di sinilah install-time script abuse jadi jebakan yang sering lolos dari checklist biasa.

Masalahnya sederhana. Banyak tim fokus ke runtime. Padahal penyerang sering memilih fase install dan build, karena di titik itu paket dapat akses ke token CI, kredensial registry, source code, sampai artefak rilis. Jadi, kalau kamu cuma audit aplikasi saat sudah running, kamu telat.

Jawaban Singkat

Install-time script abuse adalah eksekusi kode berbahaya saat dependensi dipasang atau dibuild, misalnya lewat postinstall, setup.py, build backend Python, atau native extension. Risiko utamanya bukan cuma malware lokal, tapi juga pencurian secret CI, modifikasi artefak, dan kompromi supply chain sebelum app hidup.

Karena itu, pertanyaan yang benar bukan cuma, “paket ini dipakai saat runtime atau nggak?”. Pertanyaan yang lebih penting, “apa yang dieksekusi saat install?

Install-time script abuse pada pipeline build dan dependency

Kenapa install-time script abuse lebih berbahaya dari yang kelihatan

Banyak listicle keamanan paket berhenti di typo-squatting, dependency confusion, atau paket populer yang dibajak. Itu penting. Tapi, vektor paling licin sering ada di mekanisme build itu sendiri.

  • npm bisa menjalankan preinstall, install, postinstall, prepare.
  • Python bisa mengeksekusi setup.py, hook build backend PEP 517, dan langkah kompilasi wheel.
  • Native extensions bisa menjalankan compiler, linker, skrip shell, atau fetch dependency tambahan.
  • CI pipeline sering memberi konteks rahasia yang jauh lebih berharga daripada laptop dev biasa.

Artinya, paket yang tampak “belum dipakai” tetap bisa berbahaya. Ia cukup dipasang. Selesai.

Empat jalur eksekusi yang paling sering disalahpahami

1. postinstall di npm, yarn, pnpm

Ini jalur klasik. Paket JavaScript dapat mendefinisikan skrip lifecycle yang otomatis jalan saat instalasi. Kadang alasannya sah, misalnya download binary platform-specific. Kadang juga jadi kedok paling murah untuk exfiltration.

Yang bikin repot, banyak tim melihat package.json utama, lalu merasa aman. Padahal skrip berbahaya bisa datang dari dependency transitif. Jadi, repo-mu bersih, tetapi node_modules-mu yang beraksi.

Kalau kamu ingin konteks lebih luas soal dependency transitif, baca juga cara memetakan blast radius dependency transitif.

2. setup.py di Python

Banyak developer masih menganggap setup.py sekadar file metadata lama. Faktanya, file ini adalah Python code. Kalau alur build memicunya, apa pun bisa dijalankan, mulai dari baca environment variable sampai call ke host eksternal.

Memang, ekosistem Python makin bergeser ke pyproject.toml. Namun itu bukan berarti aman otomatis. Risiko hanya pindah tempat.

3. build backend PEP 517

Ini bagian yang sering luput. Saat paket modern Python dibuild, tool seperti pip dapat memanggil build backend, misalnya setuptools, hatchling, poetry-core, atau backend kustom. Dengan kata lain, hilangnya setup.py bukan hilangnya eksekusi kode.

Justru di sini banyak tim salah paham. Mereka melihat pyproject.toml, lalu mengira prosesnya deklaratif penuh. Padahal backend tetap dapat menjalankan logika build yang kompleks. Jadi, permukaan serangannya bergeser dari file yang jelas terlihat ke mekanisme yang lebih abstrak.

4. native extensions

C, C++, Rust, dan binding native lain sering butuh kompilasi saat install. Itu normal. Namun normal bukan berarti aman. Build script, compiler flag, custom Makefile, atau unduhan dependency tambahan bisa jadi titik masuk yang sangat kuat.

Di CI, native extension bahkan lebih sensitif, karena proses build sering berjalan dengan izin luas agar artefak bisa dirilis lintas platform.

Risiko setup.py build backend dan native extension

Pola pikir yang sering salah, lalu bikin tim kecolongan

Salah satu ide paling penting di sini, paket devDependency juga bisa sangat berbahaya. Banyak kebijakan internal lebih keras ke dependency production, tetapi longgar ke tool build, linter, bundler, test helper, atau generator code.

Padahal buat penyerang, dependency yang hanya hidup di CI kadang justru lebih menarik. Alasannya jelas.

  • CI punya token publish.
  • CI punya akses ke signing key, kadang dalam bentuk terproteksi lemah.
  • CI bisa menulis artefak resmi.
  • CI sering dipercaya penuh oleh pipeline berikutnya.

Jadi, framework yang lebih waras adalah ini. Nilai paket dari hak akses saat install, bukan dari perannya saat runtime. Itu perubahan kecil dalam cara berpikir, tetapi efeknya besar.

Framework praktis, cek jalur eksekusi sebelum percaya paket

Aku biasa pakai pendekatan 4T. Ringkas, tetapi tajam.

  • Trigger, kapan kode bisa jalan, install, build, test, publish.
  • Trust, siapa yang memberi izin, dev laptop, CI branch biasa, release pipeline.
  • Touch, resource apa yang bisa disentuh, env var, network, filesystem, signing material.
  • Transfer, ke mana data atau artefak bisa keluar, HTTP, DNS, registry, cache, artifact store.

Kalau sebuah paket punya Trigger awal, Trust tinggi, Touch luas, dan Transfer bebas, risikonya naik tajam walau paket itu kecil dan populer.

Cara mengurangi risiko tanpa bikin developer sengsara

Batasi script install bila memungkinkan

Di ekosistem Node.js, pertimbangkan instalasi dengan kontrol lifecycle script saat audit atau bootstrap tertentu. Misalnya, evaluasi kapan --ignore-scripts aman dipakai. Lalu whitelist paket yang memang butuh build sah.

Jangan lupa, solusi ini bukan peluru perak. Beberapa paket memang rusak tanpa script install. Jadi targetnya bukan mematikan semuanya selamanya, tetapi membuat eksekusi jadi keputusan sadar.

Pisahkan job CI yang hanya butuh resolve dependency

Kalau semua job punya secret yang sama, satu paket nakal cukup untuk meratakan semuanya. Lebih aman kalau job lint, test, build, dan publish dipisah. Beri secret hanya saat tahap benar-benar perlu.

Ini nyambung juga dengan topik yang kubahas di kenapa lockfile yang sudah dipin tetap bisa kecolongan. Lockfile membantu integritas versi, tetapi nggak otomatis menutup jalur eksekusi saat build.

Gunakan egress control di CI

Ini sering diabaikan. Banyak tim rajin scan dependency, tetapi membiarkan job build bebas call ke internet mana saja. Akibatnya, exfiltration jadi terlalu mudah.

Kalau memungkinkan, batasi domain keluar. Minimal, monitor koneksi tak biasa saat fase install. Referensi bagus untuk praktik supply chain aman juga ada di dokumentasi SLSA dan panduan CISA Software Supply Chain Security Guidance.

Audit artefak build, bukan cuma source

Source repo bersih belum cukup. Kamu juga perlu tahu apakah wheel, binary, atau package hasil publish identik dengan yang seharusnya. Ini alasan provenance dan attestations makin penting.

Kalau ingin mendalami sisi ini, lanjutkan ke mengapa SBOM saja nggak cukup untuk membuktikan artefak.

Waspadai native extension yang terlihat “normal”

Paket native memang sering sah. Namun justru karena terlihat wajar, ia mudah lolos review dangkal. Cek apakah build script mengunduh sesuatu, mengubah path toolchain, atau membuka network saat kompilasi.

Keamanan postinstall dan CI untuk supply chain software

Tanda merah yang layak bikin kamu berhenti dulu

  • Skrip install obfuscated atau dipadatkan berlebihan.
  • Build step yang membaca banyak env var sensitif.
  • Unduhan biner dari domain acak saat install.
  • Native build yang butuh akses network tanpa alasan jelas.
  • Perubahan mendadak dari paket tenang menjadi banyak lifecycle hook.
  • Dependency baru pada tool release, codegen, atau test helper yang minta izin luas.

FAQ

Apakah lockfile cukup untuk mencegah install-time script abuse?

Belum. Lockfile mengunci versi, jadi integritas resolusi lebih stabil. Namun kalau versi yang terkunci memang punya skrip berbahaya, skrip itu tetap bisa jalan saat install.

Apakah pyproject.toml lebih aman daripada setup.py?

Lebih modern, iya. Lebih aman secara otomatis, belum tentu. Build backend di balik pyproject.toml tetap bisa menjalankan logika build, jadi kamu tetap perlu audit jalur eksekusinya.

Kenapa devDependency juga perlu diperlakukan serius?

Karena banyak devDependency berjalan di CI, build, test, atau release. Di titik itu, paket bisa mendapat akses ke token, artefak, dan rahasia yang lebih sensitif daripada runtime production.

Penutup

Kalau selama ini fokusmu cuma pada aplikasi yang sudah running, sekarang saatnya geser sudut pandang. Banyak kompromi supply chain justru dimulai sebelum binary final lahir, yaitu saat dependency dipasang dan artefak dibuild.

Mulai audit dari pertanyaan paling sederhana. Siapa yang boleh mengeksekusi apa, pada fase install yang mana, dengan akses ke resource apa? Begitu pertanyaan itu jadi kebiasaan, kamu akan melihat risiko yang sebelumnya tersembunyi.

Kalau kamu mau, aku bisa lanjut bikin seri berikutnya. Misalnya playbook audit postinstall untuk npm, checklist build backend Python, atau hardening CI untuk native extensions. Tulis di komentar, lalu subscribe juga buat update artikel supply chain security berikutnya.

About the Author

Dzul Qurnain

Suka nonton Anime, ngoding dan bagi-bagi tips kalau tahu.. Oh iya, suka baca ( tapi yang menarik menurutku aja)... Praktisi WordPress, web development, SEO, dan server administration yang membagikan tutorial teknis dan catatan implementasi nyata.

View All Articles