Cooldown 1 Hari Memblokir 70% Rilis npm yang Dibajak di 2026. Untuk Typosquat, 7 Hari Masih Meloloskan 45%
Poin penting
- Untuk paket npm yang dibajak, median jendela dari publish sampai advisory adalah 4,9 jam, jadi cooldown 1 hari memblokir 70,4% dan cooldown 3 hari memblokir 81,3%.
- Untuk paket npm yang jahat sejak lahir, median jendelanya 100,5 jam, dan cooldown 7 hari pun hanya memblokir 55,0%.
- Dari 11.556 paket npm dan PyPI berbahaya, median jendelanya 72,4 jam, tetapi p75 mencapai 28,9 hari dan p90 103,0 hari.
- Dengan cooldown 3 hari, 22,7% perbaikan keamanan baru sampai ke Anda setelah disclosure, dan dengan cooldown 7 hari angkanya naik jadi 46,1%, kecuali update keamanan dikecualikan.
- pnpm 11 menyalakan cooldown 1 hari secara default, npm menambahkan min-release-age di 11.10.0, dan pip menambahkan --uploaded-prior-to di 26.0.
Versi bahasa Inggris dengan metodologi lengkap: A 1-Day Cooldown Would Have Blocked 70% of 2026’s Hijacked npm Releases.
Pada 8 Oktober, seseorang mem-push tensorlake@0.5.144 ke npm dengan worm pencuri kredensial di hook preinstall. Socket menandainya 11 menit kemudian. Advisory OSV muncul 1,7 jam setelah publish, dan npm menggantinya dengan placeholder keamanan 3,1 jam setelah publish. Kalau installer Anda menolak rilis yang umurnya kurang dari sehari, versi itu tidak pernah sampai ke mesin Anda.
Saya mengambil semua advisory paket berbahaya OSV untuk npm dan PyPI dari 1 Januari sampai 24 Oktober 2026, lalu bertanya untuk tiap paket: apakah cooldown 1, 3, atau 7 hari akan menahannya?
Untuk rilis hasil pembajakan paket npm asli, cooldown 1 hari memblokir 70,4%. Untuk paket yang berbahaya sejak hari pertama, cooldown 7 hari masih meloloskan 45%.
Ringkasan untuk pembaca non-teknis
- “Cooldown” membuat installer mengabaikan rilis yang lebih baru dari N hari. Banyak malware tertangkap sebelum sempat setua itu.
- Kalau penyerang membajak paket asli yang tepercaya, versi jahatnya cepat ditandai: median 4,9 jam. Menunggu 1 hari akan memblokir 70,4% dari semuanya di 2026, menunggu 3 hari 81,3%.
- Paket yang palsu sejak awal, misalnya nama mirip, bertahan jauh lebih lama. Menunggu 7 hari pun meloloskan 45% dari mereka. Melawannya butuh pengecekan nama, bukan menunggu.
- Biayanya: dengan cooldown 3 hari, 22,7% perbaikan keamanan baru sampai ke Anda setelah kerentanannya publik, kecuali update keamanan dikecualikan. Renovate dan Dependabot melakukannya otomatis. pnpm, npm, dan uv memungkinkan pengecualian manual per paket.
Kenapa sekarang
- ChainDrop, 4 Agustus. Microsoft menjelaskan varian Mini Shai-Hulud yang menyebar sendiri dan menyerang “lebih dari 400 paket npm”, termasuk ekosistem
keyv,flat-cache, dancache-manager. Worm ini mencuri token publish, menaikkan versi patch, lalu merilis ulang (Microsoft Security Blog). Di data saya,flat-cache@6.1.24dapat advisory OSV 0,5 jam setelah publish,cache-manager@7.2.101,0 jam,keyv@6.0.01,7 jam. - Tensorlake, 8 Oktober. Keluarga worm yang sama. Versi jahat dipublikasikan pukul 01:12:07 UTC dan terdeteksi pukul 01:23:10 UTC (Socket, The Hacker News).
- MALFEX, Oktober. Kebalikannya. Delapan paket npm berbahaya, 40.767 unduhan, dengan
function-flagsaja 37.419 unduhan dan pertama kali terbit pada Juli 2024 (The Hacker News). Versi 1.7.3 miliknya tayang 429 hari sebelum advisory OSV muncul. Cooldown tidak menolong di sini.
Tooling sudah menyusul. npm merilis min-release-age di 11.10.0, pip merilis --uploaded-prior-to di 26.0, dan pnpm 11 menyalakan cooldown 1 hari secara default. Dokumentasi pnpm membenarkannya begini: “In most cases, malicious releases are discovered and removed from the registry within an hour.” Saya ingin menguji kalimat itu.
Metode
Semuanya dijalankan pada 25 Oktober 2026 dari laptop Windows.
- Advisory. Saya mengunduh ekspor massal OSV untuk npm dan PyPI, menyimpan entri
MAL-*yang terbit 2026-01-01 sampai 2026-10-24, dan membuang yang ditarik. Tersisa 12.820 advisory npm dan 1.545 PyPI. - Waktu publish. Untuk npm saya membaca field
timedi tiap packument. npm menyimpan timestamp versi yang dihapus dan waktu placeholder0.0.1-securitymenggantikan paket. Untuk PyPI saya memakaiupload_timedari JSON API. - Jendela waktu. Untuk tiap paket:
publisheddi OSV dikurangi waktu publish versi jahat pertama. Hanya versi pertama yang dihitung, karena cooldown tetap menginstal versi lama. - Terblokir. Cooldown D hari memblokir paket jika jendelanya lebih pendek dari D.
- Dibajak vs jahat sejak lahir. “Dibajak” berarti paket npm asli dengan rilis bersih sebelum versi jahat dan masih hidup sampai sekarang. Sisanya (typosquat, dependency confusion, spam) masuk “jahat sejak lahir”. Ini heuristik.
- Biaya. Saya mengambil 200 paket npm teratas (npm-high-impact) dan 200 paket PyPI teratas (daftar hugovk), memeriksa setiap rilis stabil dari 28 April sampai 25 Oktober, lalu mengukur seberapa sering cooldown menahan “latest”. Rilis juga saya cocokkan dengan versi
fixeddi OSV untuk menemukan perbaikan keamanan.
Timestamp OSV adalah batas atas deteksi: tensorlake ditandai Socket 91 menit sebelum OSV punya entri.
Hasil: apa yang diblokir cooldown

Dari 11.556 paket dengan timestamp yang bisa dipakai, median jendelanya 72,4 jam, hampir persis 3 hari. Lalu ekornya mengambil alih: p75 adalah 28,9 hari dan p90 103,0 hari.
| Populasi (per paket) | n | Median jendela | Cooldown 1 hari | 3 hari | 7 hari | 14 hari |
|---|---|---|---|---|---|---|
| Paket npm dibajak | 1.336 | 4,9 jam | 70,4% | 81,3% | 85,1% | 87,4% |
| Semua npm + PyPI | 11.556 | 72,4 jam | 37,7% | 49,9% | 58,4% | 65,1% |
| npm jahat sejak lahir | 10.160 | 100,5 jam | 33,5% | 45,8% | 55,0% | 62,3% |
| npm, jam takedown registry | 9.923 | 130,9 jam | 33,1% | 43,8% | 52,4% | 58,9% |

Kalimat di dokumentasi pnpm itu terlalu optimis. Hanya 13,1% paket yang mendapat advisory dalam satu jam sejak versi jahat pertama. Bahkan untuk pembajakan, kasus tercepat, angkanya 10,0% dalam satu jam dan 59,7% dalam enam jam.
Cooldown adalah pertahanan terhadap pembajakan. Worm dan rilis dari token curian menyerang paket populer, jadi scanner mengerubunginya, dan menunggu sehari terbayar. Typosquat menunggu salah ketik atau nama halusinasi asisten AI. Tidak ada yang mengawasi, jadi mereka hidup berminggu-minggu.
Penghapusan di registry tertinggal dari advisory di bagian ekor. Di mana npm memasang placeholder, itu datang sebelum advisory OSV untuk 60,6% paket, tetapi yang lambat jauh lebih lambat, sehingga median jendela takedown 5,5 hari.
PyPI menghapus proyek berbahaya sepenuhnya, jadi hanya 60 paket PyPI yang timestamp-nya bisa dipakai. Saya tidak menarik kesimpulan PyPI dari situ.
Hasil: berapa biaya cooldown
Selama 180 hari, 239 dari 400 paket teratas memindahkan versi terbarunya minimal sekali. Untuk paket-paket itu, inilah seberapa sering cooldown menjauhkan Anda dari rilis terbaru:
| Cooldown | Tertahan (npm + PyPI, aktif) | Rilis npm tak pernah terinstal | Rilis PyPI tak pernah terinstal | Perbaikan keamanan tiba setelah disclosure (dari 141) |
|---|---|---|---|---|
| 1 hari | 3,94% waktu | 17,8% | 24,4% | 21 (14,9%) |
| 3 hari | 9,71% | 30,1% | 43,2% | 32 (22,7%) |
| 7 hari | 18,53% | 44,4% | 57,5% | 65 (46,1%) |
| 14 hari | 29,48% | 55,2% | 68,7% | 86 (61,0%) |
Saat tertahan, Anda biasanya hanya tertinggal 1,1 sampai 1,7 versi untuk cooldown 1 sampai 7 hari.
Kolom keamanan adalah biaya sebenarnya. Saya menghitung perbaikan sebagai terlambat jika Anda masih di versi rentan setelah advisory-nya publik. Disclosure biasanya datang jauh setelah perbaikan: median selisihnya 12,8 hari di npm dan 7,9 hari di PyPI. Itu sebabnya cooldown 1 hari murah. Pada 7 hari, hampir separuh perbaikan baru tiba setelah advisory publik.

Naik dari 3 ke 7 hari menambah 8,5 poin pemblokiran malware dan 23,4 poin perbaikan keamanan yang terlambat. Pada 14 hari, kedua kurva hampir bertemu.
Pengaturan untuk stack Anda
Setiap opsi di bawah sudah saya cek ke dokumentasi resmi pada 25 Oktober 2026.
pnpm (pnpm-workspace.yaml, dalam menit; default 1440 sejak v11):
minimumReleaseAge: 4320 # 3 days
minimumReleaseAgeExclude:
- '@myorg/*'
- nx@21.6.5
npm (11.10.0 ke atas, dalam hari; min-release-age-exclude butuh 11.17.0):
# .npmrc
min-release-age=3
npm install --min-release-age-exclude='@myorg/*'
uv (menerima durasi sederhana, durasi ISO 8601 seperti P3D, atau timestamp):
[tool.uv]
exclude-newer = "3 days"
exclude-newer-package = { cryptography = false }
pip (26.1 ke atas untuk durasi; index harus menampilkan waktu upload):
pip install --uploaded-prior-to P3D -r requirements.txt
# or: PIP_UPLOADED_PRIOR_TO=P3D
Renovate (security:minimumReleaseAgeNpm dan security:minimumReleaseAgePypi masing-masing menetapkan 3 hari):
{
"extends": ["security:minimumReleaseAgeNpm", "security:minimumReleaseAgePypi"]
}
Dependabot (update versi sudah default cooldown 3 hari; ini membuatnya eksplisit):
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
cooldown:
default-days: 3
exclude: ["@myorg/*"]
Kapan cooldown merugikan
Bot sudah menangani masalah perbaikan keamanan. Dokumentasi Renovate menyebut “Security updates bypass any minimumReleaseAge checks”, dan dokumentasi Dependabot menyebut “The cooldown option is only available for version updates, not security updates.” Kalau PR upgrade Anda dibuka oleh bot, angka 22,7% saya sebagian besar tidak berlaku.
Cooldown di level installer tidak tahu mana perbaikan keamanan. Di npm, jika min-release-age memblokir versi yang sudah ditambal, npm audit fix membiarkan Anda di versi rentan, memberi peringatan, dan keluar dengan kode non-nol. Mode gagal yang benar, tetapi Anda butuh playbook:
- CVE mendesak di satu paket: tambahkan ke daftar exclude (
minimumReleaseAgeExclude,min-release-age-exclude,exclude-newer-package = { pkg = false }), instal, lalu hapus entrinya. pnpm 11.22 bisa memangkas entri basi denganminimumReleaseAgeExcludePrune. - Paket milik sendiri: kecualikan scope organisasi Anda secara permanen.
- Pin dengan versi persis, bukan nama, bila bisa. pnpm menerima
nx@21.6.5agar pengecualian tidak diam-diam mencakup rilis berikutnya.
Catatan batasan
publisheddi OSV adalah saat entri masuk OSV, bukan saat seseorang pertama kali menyadari. Deteksi nyata sering lebih awal, jadi angka saya konservatif.- Label “dibajak” adalah heuristik.
- Timestamp PyPI hanya bertahan untuk paket yang tidak dihapus, jadi 60 paket adalah sampel yang bias.
- Model biaya mengasumsikan Anda selalu ingin versi stabil terbaru, dan 141 perbaikan adalah sampel kecil.
- Cooldown tidak berguna melawan paket yang jahat sejak hari pertama dan sengaja Anda instal.
function-flagmilik MALFEX bertengger di npm selama 429 hari.
Pengaturan saya setelah semua ini: 3 hari untuk npm dan PyPI, pengecualian untuk scope sendiri, dan update keamanan lewat Renovate agar lolos antrean. Jika diputar ulang terhadap 2026, itu memblokir 81,3% pembajakan dengan harga 9,71% waktu tertahan.
Cooldown apa yang Anda pakai, dan pernahkah Anda butuh pintu darurat untuk CVE sungguhan?
Terkait: backdoor supply chain LiteLLM dan playbook ekstensi browser palsu, kini hadir sebagai agent skills.
Pertanyaan yang sering diajukan
- Bagaimana cara mengatur cooldown dependensi di npm, pnpm, uv, dan pip?
- Di pnpm, atur minimumReleaseAge di pnpm-workspace.yaml (dalam menit, 4320 untuk 3 hari). Di npm 11.10.0 ke atas, set min-release-age=3 di .npmrc. Di uv, set exclude-newer = '3 days' di bawah [tool.uv]. Di pip 26.1 ke atas, pakai --uploaded-prior-to P3D atau PIP_UPLOADED_PRIOR_TO=P3D.
- Berapa banyak malware yang diblokir cooldown?
- Untuk paket npm yang dibajak, cooldown 1 hari memblokir 70,4% dan cooldown 3 hari 81,3%. Untuk paket npm yang jahat sejak lahir seperti typosquat, cooldown 7 hari hanya memblokir 55,0%, jadi 45% tetap lolos.
- Apa biaya dari cooldown?
- Dengan cooldown 3 hari, 22,7% perbaikan keamanan sampai ke Anda setelah kerentanannya publik, dan 46,1% pada 7 hari. Renovate dan Dependabot mengecualikan update keamanan, sedangkan pnpm, npm, dan uv memungkinkan Anda mengecualikan paket secara manual.
- Bagaimana cara menginstal perbaikan keamanan mendesak saat cooldown aktif?
- Tambahkan paket ke daftar exclude (minimumReleaseAgeExclude, min-release-age-exclude, atau exclude-newer-package = { pkg = false }), instal, lalu hapus entrinya. Pin dengan versi persis, misalnya nx@21.6.5, supaya pengecualian tidak mencakup rilis berikutnya.
About the author
Security Engineer & Technical Writer
Security engineer and technical writer based in Batam, Indonesia. I review and harden MCP servers and AI agents, build security automation, and write up what holds and what fails. I also train on DNS security as a PANDI .id Academy trainer.
Artikel terkait
-
5 min read
UUIDv7 Bagus untuk Primary Key, Buruk sebagai Jam: 4 Tes Sebelum Migrasi
UUIDv7 bagus sebagai primary key database tapi buruk sebagai jam. Empat tes cepat, apa yang dibocorkan timestamp di dalamnya, dan aturan praktis pemakaiannya.
- Security Engineering
- Engineering Practice
-
9 min read
Python 3.15 Is Out. I Checked the Top 500 PyPI Packages: 97% Install From a Wheel, 12 Still Run Build Scripts
I classified the latest release of the 500 top PyPI packages for Python 3.15. 485 install from a wheel; 12 fall back to running build code, led by PyYAML.
- Engineering Practice
- Security Engineering
-
9 min read
I Read the CI of 300 Popular Repos. 145 Still Run Third-Party Actions by Tag or Branch
I parsed 4,750 workflows from 300 popular repos. 145 of 265 that use third-party actions still reference one by a movable tag or branch.
- Security Engineering
- Engineering Practice
All writing | RSS | Markdown