Safeguard
Software Supply Chain Security

Dependency Cooldown Periods as a Malware Defense

Malicious npm packages are often caught within days. Cooldown periods exploit that lag — here's how they work, and how Endor Labs and Safeguard compare.

Vikram Iyer
Security Researcher
8 min read

On September 8, 2025, a phishing email convinced a maintainer of chalk, debug, and over a dozen other npm packages with a combined 2+ billion weekly downloads to authorize a malicious publish. The injected code targeted browser wallets, rewriting transaction addresses in real time. It was caught and pulled within hours — but any team that ran npm install in that window pulled the compromised version straight into their build. This is the pattern behind nearly every recent open source supply chain incident: the malicious code doesn't stay live for long, but "not long" is still long enough to catch anyone auto-updating on publish. A dependency cooldown period — deliberately delaying adoption of new package versions by a fixed window — is one of the few defenses that works against this exact timing gap. Here's how it works, why competitors like Endor Labs have started building it into their platforms, and where Safeguard fits.

What Is a Dependency Cooldown Period?

A dependency cooldown period is a policy that blocks a package version from being installed, resolved, or promoted to production until it has existed in the public registry for a minimum amount of time — typically 3 to 14 days. Instead of your CI/CD pipeline or npm install pulling whatever was published five minutes ago, the resolver checks the package's publish timestamp against the registry and refuses (or flags) anything newer than the cooldown threshold. If a version is pulled by npm, PyPI, or the maintainer during that window — as happened with chalk/debug in September 2025, with is and other packages compromised in the same phishing wave, and with the "Shai-Hulud" self-replicating npm worm discovered in 2025 that stole credentials and republished itself into hundreds of packages — your organization never touches it. The version simply expires out of your dependency graph before it's ever resolved.

Why Do Malicious Packages Get Caught Within Hours, Not Months?

Malicious packages get caught quickly today because registry maintainers, security researchers, and automated scanners (Socket, Snyk, ReversingLabs, GitHub's own npm abuse team) actively monitor new publishes for known malware signatures, suspicious install scripts, and anomalous maintainer behavior. The chalk/debug incident was flagged and packages were unpublished or patched within roughly two to six hours of the malicious versions going live, according to public incident writeups from the affected maintainers and Socket's research team. The 2024 xz-utils backdoor (CVE-2024-3094) is the counterexample that proves the rule: it survived nearly two years of a patient social-engineering campaign but was still caught before it reached mainstream Linux distributions, because a single engineer noticed a 500-millisecond SSH login delay. The common thread across both fast npm catches and the slower xz case is that detection consistently outpaces the typical "always take latest" update cadence most teams still run. A cooldown period doesn't need to be long to be effective — it just needs to be longer than the detection window, and evidence from 2024-2025 incidents suggests that window is usually measured in hours to days, not weeks.

How Is Endor Labs Approaching Cooldown Periods?

Endor Labs has publicly framed dependency cooldowns as a core recommendation in its open source security guidance, positioning a delay-based adoption policy as a practical complement to traditional vulnerability scanning. Their pitch centers on policy-as-code: security teams define a minimum package age (often citing a multi-day default) as a gate inside their existing dependency management and reachability analysis platform, so a new version has to "sit" before it's eligible to be pulled into a build. This is a reasonable and increasingly common approach — but in most tellings of it, the cooldown is a static, org-wide number applied uniformly across your entire dependency tree, regardless of a package's actual risk profile, maintainer history, or how critical it is to your build. A brand-new, low-download utility package and a foundational library like debug get treated identically. That's a defensible starting point, but it leaves risk-based nuance and automatic override handling — what happens when a CVE fix needs to ship faster than your cooldown allows — as something teams have to bolt on themselves.

What Are the Trade-offs of Delaying Updates?

The main trade-off is that a blanket cooldown period slows down legitimate security patches at exactly the moment you need them fastest. If a critical CVE (say, a remote code execution flaw with a CVSS score of 9.8) gets patched and published on a Tuesday, a rigid 7-day cooldown means your production systems stay vulnerable until the following Tuesday even though the fix is sitting right there in the registry. This is the tension every team adopting cooldowns has to solve: too short a window and you don't get meaningful malware protection; too long and you're voluntarily running known-vulnerable code. The 2021 ua-parser-js compromise (three malicious versions published and pulled within about 24 hours) and the 2022 node-ipc protestware incident (which shipped destructive code to users in Russia and Belarus in versions published and caught within days) both show why a naive "always wait N days" rule needs an exception path for urgent, verified security fixes — otherwise the policy protects against malware while quietly reintroducing risk from unpatched vulnerabilities.

How Long Should a Cooldown Period Be?

Most security teams land on a 3-to-7-day default for general dependencies and a shorter 24-to-48-hour window for packages tied to active CVE remediation. This range is based on how quickly the ecosystem actually reacts: npm's own abuse response and third-party scanners like Socket typically flag and remove malicious packages within the first 24-72 hours of publication, based on public incident timelines from 2024-2025 (the @solana/web3.js account takeover in December 2024 was live for roughly five hours before detection; the lottie-player compromise in 2022 was caught within about a day). A 7-day cooldown would have fully protected any team from every one of the incidents named in this post. The right number isn't universal, though — it should flex based on a package's blast radius (is it a build-time dev dependency or does it run in your production runtime?), its download volume and maintainer reputation, and whether a given release is a routine minor bump or a security patch you're deliberately fast-tracking.

Does a Cooldown Period Replace Vulnerability Scanning?

No — a cooldown period is a timing control, not a detection control, and it only works alongside SCA scanning, SBOM tracking, and malicious package detection, not instead of them. Cooldowns buy time for the ecosystem's detection mechanisms to catch what your own tools might miss on day one; they do nothing against a vulnerability that's been sitting undiscovered in a package for years, like Log4Shell (CVE-2021-44228), which existed in Log4j since 2013 before being disclosed in December 2021. For that class of risk you still need continuous SCA scanning, reachability analysis to know if the vulnerable code path is actually invoked, and SBOM generation to know what's in your environment in the first place. Think of cooldowns as narrowing the specific attack window — zero-day malware injected into a legitimate package's latest release — while your broader vulnerability management program handles everything else.

How Safeguard Helps

Safeguard implements dependency cooldown periods as a configurable, risk-weighted policy rather than a single static number applied to everything. You set baseline cooldown windows (for example, 5 days for production dependencies, 2 days for dev-only tooling) and Safeguard automatically adjusts them based on package reputation signals: download volume, maintainer account age and history, whether the package has a prior incident on record, and how deep it sits in your dependency graph. When a new version is published, Safeguard holds it out of your resolvable dependency set until it clears the cooldown window or a security team member explicitly approves an early pull — with that approval logged for audit purposes.

Critically, Safeguard builds in the override path that a blanket cooldown lacks: when a CVE fix ships for something already in your SBOM, Safeguard cross-references the new version against its CVE database and reachability analysis, and if the fix addresses a reachable, exploitable vulnerability, it fast-tracks that specific version past the cooldown gate rather than making you choose between "stay vulnerable" and "manually override everything." Every blocked, held, or expedited package version is recorded against your SBOM with a timestamp and reason, so a cooldown policy becomes evidence for SOC 2 and audit purposes rather than just an internal engineering habit. If you're currently pulling latest on every dependency without a delay window, that's the single highest-leverage gap to close first — Safeguard's cooldown policies can be turned on for your existing dependency graph without re-architecting your build pipeline.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.