12 poin oleh GN⁺ 20 hari lalu | 2 komentar | Bagikan ke WhatsApp
  • Dua versi berbahaya dari klien HTTP axios yang широко digunakan dipublikasikan ke npm dan, saat dipasang, menyebarkan remote access trojan (RAT)
  • Penyerang mengunggah paket berbahaya secara manual dengan mencuri kredensial akun maintainer, sehingga melewati GitHub Actions
  • Versi berbahaya menyertakan dependensi palsu plain-crypto-js@4.2.1 yang memasang RAT lewat skrip postinstall lalu menghapus jejaknya
  • RAT menginfeksi macOS, Windows, dan Linux, lalu berkomunikasi dengan server C2 (sfrclak.com:8000) untuk mengunduh payload tambahan
  • npm dan GitHub bergerak cepat menghapus versi berbahaya tersebut, tetapi insiden ini kembali menyoroti pentingnya penguatan keamanan supply chain dan perlindungan kredensial

Ringkasan serangan supply chain axios di npm

  • Pada 31 Maret 2026, dua versi berbahaya dari library klien HTTP axios yang banyak digunakan (axios@1.14.1, axios@0.30.4) dipublikasikan ke npm
  • Penyerang mencuri kredensial npm milik maintainer utama axios, melewati pipeline CI/CD GitHub Actions, lalu menerbitkan paket berbahaya secara manual
  • Kedua versi menyisipkan dependensi palsu bernama plain-crypto-js@4.2.1, dan paket ini memasang remote access trojan (RAT) melalui skrip postinstall
  • RAT menargetkan macOS, Windows, dan Linux, lalu berkomunikasi dengan server C2 (Command and Control) (sfrclak.com:8000) untuk mengunduh payload tahap kedua
  • Setelah pemasangan, kode berbahaya dan jejaknya dihapus lalu diganti dengan package.json yang bersih untuk menghindari deteksi forensik

Linimasa serangan

  • 30 Maret 05:57 UTC: plain-crypto-js@4.2.0 (versi normal) dipublikasikan
  • 30 Maret 23:59 UTC: plain-crypto-js@4.2.1 (versi berbahaya) dipublikasikan, dengan hook postinstall ditambahkan
  • 31 Maret 00:21 UTC: axios@1.14.1 dipublikasikan, dengan dependensi berbahaya disisipkan
  • 31 Maret 01:00 UTC: axios@0.30.4 dipublikasikan, dengan dependensi berbahaya yang sama disisipkan
  • 31 Maret 03:15 UTC: npm menghapus dua versi berbahaya tersebut
  • 31 Maret 04:26 UTC: npm mengganti plain-crypto-js dengan security holder stub (0.0.1-security.0)

Gambaran umum axios

  • axios adalah klien HTTP yang paling banyak digunakan di ekosistem JavaScript, dipakai baik di Node.js maupun browser
  • Dengan lebih dari 300 juta unduhan mingguan, satu rilis berbahaya saja bisa menimbulkan potensi dampak yang sangat luas
  • Pengembang biasa sulit menyadari pemasangan kode berbahaya saat menjalankan npm install

Tahapan serangan

  • Tahap 1 — Pengambilalihan akun maintainer

    • Penyerang mengambil alih akun npm jasonsaayman dan mengubah email menjadi ifstap@proton.me
    • Setelah itu, build berbahaya dipublikasikan ke branch rilis 1.x dan 0.x
    • Rilis normal biasanya dipublikasikan melalui OIDC Trusted Publisher di GitHub Actions, tetapi axios@1.14.1 dipublikasikan secara manual tanpa gitHead dan tanpa tanda tangan OIDC
    • Diduga penyerang menggunakan token akses npm yang berlaku jangka panjang
  • Tahap 2 — Pra-distribusi dependensi berbahaya

    • plain-crypto-js@4.2.1 dipublikasikan oleh akun nrwise@proton.me
    • Paket ini menyamar sebagai crypto-js dengan memakai deskripsi dan URL repositori yang sama
    • Menyertakan hook "postinstall": "node setup.js" yang berjalan otomatis saat instalasi
    • Setelah serangan, package.md diganti menjadi package.json untuk menyiapkan penghapusan bukti
  • Tahap 3 — Penyisipan dependensi ke axios

    • plain-crypto-js@^4.2.1 ditambahkan sebagai dependensi runtime
    • Tidak pernah di-import satu kali pun di dalam kode → phantom dependency
    • Saat npm install, paket ini otomatis terpasang dan menjalankan skrip postinstall

Analisis dropper RAT (setup.js)

  • Teknik obfuscation

    • String disimpan dalam array stq[] dalam bentuk terenkripsi lalu didekripsi dengan _trans_1 (XOR) dan _trans_2 (Base64+dibalik)
    • URL C2 adalah http://sfrclak.com:8000/6202033
    • String hasil dekripsi mencakup identifier OS (win32, darwin), path file, dan perintah shell
  • Payload per platform

    • macOS

      • AppleScript ditulis ke /tmp lalu dijalankan dengan osascript
      • Binary RAT diambil dari C2, disimpan ke /Library/Caches/com.apple.act.mond, lalu dieksekusi
      • Nama file disamarkan seperti daemon sistem Apple
    • Windows

      • Menelusuri path PowerShell lalu menyalin ke %PROGRAMDATA%\wt.exe
      • Mengunduh dan menjalankan PowerShell RAT dari C2 melalui VBScript
      • File sementara (.vbs, .ps1) dihapus setelah eksekusi
    • Linux

      • Mengunduh /tmp/ld.py dengan curl lalu menjalankannya menggunakan nohup python3
      • File /tmp/ld.py tetap tertinggal
      • Di ketiga platform, body POST packages.npm.org/product0~2 digunakan untuk menyamar sebagai trafik npm yang sah
  • Penghapusan diri dan penyamaran

    • setup.js dan package.json dihapus
    • package.md diganti menjadi package.json untuk menyamar sebagai paket normal
    • Setelah itu, deteksi melalui npm audit atau peninjauan manual menjadi tidak mungkin
    • Namun, keberadaan node_modules/plain-crypto-js/ sendiri merupakan bukti infeksi

Verifikasi eksekusi dengan StepSecurity Harden-Runner

  • Harden-Runner mencatat event jaringan, proses, dan file secara real-time di GitHub Actions
  • Saat axios@1.14.1 dipasang, terdeteksi dua koneksi ke C2 (curl, nohup)
    • Koneksi pertama terjadi 2 detik setelah npm install dimulai
    • Koneksi kedua terjadi 36 detik kemudian dan terus berjalan sebagai proses background
  • Hasil analisis pohon proses menunjukkan proses nohup menjadi orphan process di bawah PID 1(init) dan tetap berjalan
  • Di log event file, package.json tertimpa dua kali
    • Pertama: versi berbahaya ditulis saat instalasi
    • Kedua: 36 detik kemudian diganti dengan stub bersih

Indicator of Compromise (IOC)

  • Paket npm berbahaya

    • axios@1.14.1 · shasum: 2553649f232204966871cea80a5d0d6adc700ca
    • axios@0.30.4 · shasum: d6f3f62fd3b9f5432f5782b62d8cfd5247d5ee71
    • plain-crypto-js@4.2.1 · shasum: 07d889e2dadce6f3910dcbc253317d28ca61c766
  • Jaringan

  • Path file

    • macOS: /Library/Caches/com.apple.act.mond
    • Windows: %PROGRAMDATA%\wt.exe
    • Linux: /tmp/ld.py
  • Akun penyerang

    • jasonsaayman (maintainer yang dibajak)
    • nrwise (akun yang dibuat penyerang)
  • Versi aman

    • axios@1.14.0 (aman)

Verifikasi dampak dan prosedur respons

  • Periksa 1.14.1 / 0.30.4 di npm list axios atau package-lock.json
  • Periksa apakah node_modules/plain-crypto-js ada
  • Jika file RAT per OS ditemukan, anggap sistem telah terkompromi sepenuhnya
  • Tinjau riwayat instalasi versi tersebut di log CI/CD lalu ganti semua secret dan token

Langkah pemulihan

  1. Kunci axios ke versi aman (1.14.0 atau 0.30.3)
  2. Hapus folder plain-crypto-js lalu instal ulang dengan npm install --ignore-scripts
  3. Jika ditemukan jejak RAT, bangun ulang sistem
  4. Rotasi semua kredensial (AWS, SSH, CI/CD, dll.)
  5. Audit pipeline CI/CD dan ganti secret
  6. Gunakan opsi --ignore-scripts pada build otomatis
  7. Blokir domain/IP C2 lewat firewall atau /etc/hosts

Fitur StepSecurity Enterprise

  • Harden-Runner

    • Menerapkan whitelist trafik keluar jaringan di GitHub Actions
    • Memblokir trafik abnormal dan mencatat log
    • Dapat memblokir koneksi ke sfrclak.com:8000 lebih awal
  • Dev Machine Guard

    • Memantau paket npm yang dipasang di PC developer secara real-time
    • Langsung mendeteksi perangkat yang memasang axios@1.14.1, 0.30.4
  • npm Package Cooldown Check

    • Menerapkan masa tunda pemblokiran instalasi sementara untuk paket yang baru dipublikasikan
    • Dapat mendeteksi publikasi berbahaya cepat seperti plain-crypto-js@4.2.1
  • Compromised Updates Check

    • Memblokir merge PR berdasarkan database paket berbahaya real-time
    • axios@1.14.1, plain-crypto-js@4.2.1 langsung terdaftar
  • Package Search

    • Mencari lokasi adopsi paket tertentu di seluruh PR dan repositori organisasi
    • Cakupan dampak (repositori, tim, PR) bisa segera diketahui
  • AI Package Analyst

    • Memantau registry npm secara real-time dan melakukan deteksi berbahaya berbasis perilaku
    • Kedua versi berbahaya terdeteksi dalam hitungan menit setelah dipublikasikan
  • Threat Center Alert

    • Menyediakan peringatan intelijen ancaman berisi ringkasan serangan, IOC, dan prosedur respons
    • Memberikan visibilitas real-time melalui integrasi SIEM

Ucapan terima kasih

  • Maintainer axios dan komunitas merespons cepat melalui GitHub issue #10604
  • GitHub menangguhkan akun yang dibajak dan npm menghapus versi berbahaya serta menerapkan security holder
  • Respons kolaboratif antara maintainer, GitHub, dan npm membantu meminimalkan dampak bagi developer di seluruh dunia

2 komentar

 
chanapple 20 hari lalu

Saya tidak pernah membayangkan paket sebesar ini bisa dibobol, tetapi axios benar-benar di luar dugaan.

 
GN⁺ 20 hari lalu
Komentar Hacker News
  • npm, bun, pnpm, dan uv kini semuanya mendukung pengaturan usia rilis minimum paket
    Saya menambahkan ignore-scripts=true ke ~/.npmrc, dan pengaturan ini saja sudah bisa memitigasi kerentanan tersebut
    bun dan pnpm secara bawaan tidak menjalankan skrip lifecycle
    Contoh konfigurasi untuk tiap package manager adalah sebagai berikut:

    • uv: exclude-newer = "7 days"
    • npm: min-release-age=7
    • pnpm: minimum-release-age=10080
    • bun: minimumReleaseAge = 604800
      Menariknya, masing-masing memakai satuan waktu yang berbeda
      Jika menggunakan agen LLM, pengaturan ini bisa menyebabkan kegagalan, jadi perlu menambahkan panduan terkait di AGENTS.md atau CLAUDE.md
    • Ada lelucon menanggapi kalimat “satuan waktunya semua berbeda” dengan, “baru hari pertama pakai JavaScript ya?
    • pnpm adalah yang paling dulu memperkenalkan fitur ini. npm hanya mendukungnya mulai 11.10.0 ke atas, tersedia sejak rilis 11 Februari 2026
    • Ada juga pendapat bahwa sebaiknya satuan dituliskan langsung di nama opsi konfigurasi, misalnya timeoutMinutes alih-alih timeout
    • npm mungkin tidak mendukung komentar. min-release-age=7 # days bisa jadi sebenarnya tidak diterapkan
    • Untuk yarn berry, ini bisa diatur di ~/.yarnrc.yml dengan npmMinimalAgeGate: "3d"
  • Banyak yang kaget mendengar Axios terkena serangan rantai pasok
    Axios sendiri tidak berisi kode berbahaya, tetapi ada dependensi palsu bernama plain-crypto-js@4.2.1 yang disisipkan untuk menjalankan skrip postinstall yang memasang RAT (remote access trojan)
    Ini kabar baik bagi pengguna yang, seperti di pnpm atau bun, harus menyetujui skrip postinstall secara manual

    • fetch baru tersedia bawaan di Node.js sejak v18, dan baru stabil mulai v21. Axios sudah ada jauh lebih lama dan masih banyak dipakai karena masuk ke banyak framework dan tutorial
    • Saat ada yang berkata “pengguna pnpm/bun aman”, muncul pertanyaan, “kalau di versi lama mereka mungkin sudah pernah menyetujuinya, bukan?”
    • Ada juga yang bertanya apakah pnpm juga memblokir postinstall pada dependensi turunan
  • Ada pendapat bahwa package manager adalah eksperimen yang gagal
    Ada pustaka C berkualitas tinggi seperti SQLite yang terdiri dari satu berkas .c, dan pendekatan seperti itu bisa menghindari masalah transitive dependency
    Sebagian besar permukaan serangan berasal dari dependensi tidak langsung seperti ini

    • Package manager kini sudah menjadi bagian penting dari adopsi bahasa pemrograman. Masalah utamanya adalah kurangnya kontrol kualitas dan struktur insentif
      Bahkan OpenSSL pun sedang ditulis ulang karena masalah kualitas kode, dan di JS, perluasan standard library sulit sehingga polyfill menjamur
    • Ada juga pendapat bahwa “solusi yang butuh sedikit usaha ekstra tidak akan diterima komunitas”
      Sebagai gantinya, diusulkan agar repo seperti npm memperketat standar kualitas dan hanya mendaftarkan maintainer yang bertanggung jawab
    • Dalam pengembangan web, permukaan serangan jauh lebih luas. Menyalin manual membuat pembaruan sulit dilacak, sehingga fitur notifikasi package manager tetap berguna
    • Ada pula yang menyoroti bahwa hanya NPM yang tampak sebagai ekosistem dengan serangan rantai pasok sangat parah
    • Ada bantahan bahwa Rust lebih aman daripada C, dan kebanyakan crate berkualitas tinggi, jadi argumen yang terlalu berpusat pada pustaka C dianggap berlebihan
  • Muncul gurauan bahwa mereka memulai hari dengan sapaan sinis, “paket npm mana lagi yang dibobol hari ini?

  • Untuk pengguna Linux, ada rekomendasi memakai bwrap agar semua logika build seperti npm, pip, cargo, gradle, dan lainnya bisa disandbox
    bwrap menyediakan lingkungan terisolasi seperti Docker tetapi tidak membutuhkan image. Flatpak juga dibangun di atas teknologi yang sama
    Saat deploy ke server, hardening container itu penting, dan inti utamanya adalah memperlakukan lingkungan CI/CD sebagai area yang tidak dipercaya
    Saat menjalankan AI pun, sebaiknya sandbox yang sama dipakai

    • Namun ada yang menyoroti bahwa cara ini hanya efektif untuk serangan postinstall. Kode bisa tetap berjalan hanya dengan require
    • Ada juga yang membuat sandbox pribadi berbasis Docker bernama amazing-sandbox
    • drop, sebuah alat tingkat lebih tinggi dibanding bwrap, juga direkomendasikan
    • Ada pendapat bahwa firejail adalah sandbox keamanan yang lebih fleksibel
    • SSH socket forwarding memungkinkan akses ke private key, sehingga tidak memberi keuntungan keamanan, dan lebih baik memakai key yang dilindungi kata sandi
  • Setelah terus melihat masalah dependensi berulang, ada kekhawatiran bahwa ekosistem Rust suatu hari juga bisa mengalami hal serupa
    Sulit untuk membesarkan standard library, tetapi tetap dibutuhkan sistem jaminan kualitas paket yang tepercaya

    • Ada usulan bahwa paket besar seperti Axios harus mewajibkan beberapa approver MFA untuk menyetujui publikasi
    • Ada juga prediksi akan muncul layanan komersial yang menyediakan dependensi terverifikasi
    • Usulan lain adalah menyalin sendiri pengujian dependensi ke dalam codebase, lalu melewatinya lewat proses code review internal
      Berkat AI, pekerjaan tambahan seperti ini sekarang jadi memungkinkan, dan ada refleksi bahwa sebenarnya cara seperti ini seharusnya sudah dilakukan sejak dulu
  • Aturan inti untuk meminimalkan paparan terhadap serangan rantai pasok NPM

    • Menggunakan mode zero-installs milik Yarn
    • Menonaktifkan skrip postinstall atau memeriksanya sebelum dijalankan
    • Jika kode pihak ketiga dijalankan saat pengembangan, jalankan hanya di dalam VM/container
    • Saat menambahkan paket, anggap popularitas sebagai nilai plus, commit terbaru sebagai faktor minus, lalu tinjau langsung kode dan riwayat perubahannya
    • Verifikasi seluruh pohon dependensi, dan setiap kali ada developer baru ditambahkan, evaluasi ulang apakah mereka layak dipercaya
    • Ada juga pendapat bahwa lockfile dan opsi --frozen-lockfile saja sudah memberi perlindungan yang cukup
    • Ada pula orang dengan filosofi sederhana namun kuat: “saya hanya menghindari stack yang penuh masalah
  • Menanggapi pertanyaan “bagaimana cara sepenuhnya menghindari serangan seperti ini?”,
    ada yang berkata ingin beralih ke Qubes OS agar password manager dan lingkungan build benar-benar terpisah

    • Ada tim yang hanya menjalankan pekerjaan terkait NPM di dalam container Apple, dan berencana memindahkan Python dan Rust dengan cara yang sama
      Mereka mengibaratkan ini seperti APD di laboratorium kimia: lingkungan pengembangan juga butuh isolasi dan perlindungan
      pip juga sudah mulai mencegah instalasi di luar virtualenv, dan mereka berharap package manager nantinya menyediakan opsi untuk menolak berjalan di luar sandbox
    • Ada juga yang mengatakan mereka sama sekali tidak memasang Node.js/npm di sistem. Sejauh ini mereka belum pernah merasa benar-benar perlu
  • pnpm dan bun kini secara bawaan mengabaikan skrip postinstall, tetapi npm masih tetap menjalankannya
    Disarankan menetapkan ignore-scripts=true di ~/.npmrc
    npm masih mencatat 80 juta unduhan per minggu

  • Ada dugaan bahwa kebocoran kredensial dalam insiden ini kemungkinan berasal dari insiden LiteLLM sebelumnya
    Memakai Python atau Node.js terasa mengkhawatirkan, tetapi sebenarnya ini dianggap masalah yang bersifat umum

    • Pengaturan usia rilis minimum memang membantu, tetapi banyak yang masih merasa takut memperbarui dependensi
    • Ada klaim bahwa insiden Trivy, bukan LiteLLM, adalah akar penyebabnya
    • Ada juga saran untuk menjalankannya di container sementara tanpa root agar cakupan dampak bisa dibatasi