Contents
Introduction
Part 1 showed how supply chain attacks work through the axios case, and Part 2 covered three defense strategies applied to a real-world project. The common principle behind all three can be summarized in a single sentence:
Do not immediately accept newly published versions.
This article sets out to answer two questions:
- How effective is this simple principle in practice?
- And what does it fail to stop?
The Time Pattern of Attacks
The argument that supply chain attacks can be stopped by a time-based defense starts from the following observation:
The time between a malicious package being published and its detection and removal is almost always a matter of hours to days.
This pattern holds because:
- Popular packages are analyzed immediately by automated security scanners (Socket, Snyk, GitHub Advisory, etc.)
- Developers who notice suspicious behavior file issues right away
- The maintainer or npm staff unpublishes the package as soon as it is discovered
In other words, an attacker’s opportunity is limited to the window of exposure — the brief period from when the malicious version is live until it is detected and removed. In supply chain attacks, this window is typically very short. Within a few days, the malicious version is gone from the registry and a clean new version has taken its place. Anyone who decided to wait a few days before accepting new versions naturally sidesteps this window entirely.
Window of Exposure in Known Incidents
Looking at representative npm supply chain incidents:
| Incident | Year | Window of exposure (publish → removal) |
|---|---|---|
| ua-parser-js | 2021 | ~4 hours |
| Ledger Connect Kit | 2023 | ~5 hours |
| Solana web3.js | 2024 | ~5 hours |
| axios | 2026 | ~4 hours |
Not one of them lasted more than 24 hours. Waiting even a single day would have been enough to avoid having any of these malicious versions reach a production environment.
The Cooldown Period in Supply Chain Defense
Since supply chain attack windows are typically very short, a simple gate that delays acceptance of new versions by a few days yields significant defensive value. But how many days should that gate be?
The name for this waiting period varies by tool:
- Dependabot:
cooldown - pnpm · Renovate · Yarn:
minimumReleaseAge(ornpmMinimalAgeGate) - bun · uv:
minimumReleaseAgeandexclude-newer, respectively
Different names, same idea: “Exclude any version published less than N days ago from installation and PR creation.” And the industry’s recommended value for N converges consistently on 7 days.
This section examines that 7-day figure from three angles: rationale, recommendation, and trade-offs.
1. Rationale: Where Major Tools and Security Research Converge
Seven days is not arbitrary — it is the value that multiple package managers and security research tools have independently adopted or recommended.
| Source | Recommended / default | Notes |
|---|---|---|
GitHub Dependabot cooldown official docs | 7 days in example config | Official reference recommendation |
pnpm minimumReleaseAge (v11) | Default: 1 day | Conservative default for backward compatibility; guide recommends longer |
| pnpm supply chain security guide | 7 days | Strongly discourages installing versions less than 7 days old |
| Renovate minimum-release-age | Documentation provided | Listed as an official key concept |
| Socket | 7-day flag | Automatically flags versions published less than 7 days ago as a risk signal |
The key observation is that GitHub’s official documentation, major package managers (pnpm, Renovate), and supply chain security SaaS (Socket) all treat 7 days as “enough time to filter short-lived malicious publishes.”
2. Recommendation: Start with 7 Days
In summary:
For new projects, set 7 days as your starting point.
The reason 7 days has become the standard recommendation is clear when compared to 1 day or 30 days.
- 1 day is not enough. Packages with fewer users, weekend/holiday publishes, and maintainers on vacation can all delay detection. 1 day only filters the critical 4–5 hour incidents.
- 30 days is excessive. It blocks marginally more attacks, but delays adoption of new features and improvements. It also lets lockfiles grow stale, creating other operational overhead.
- 7 days is the consensus sweet spot. It filters almost all short-lived malicious publishes while letting legitimate new versions through within a week.
Validating this against real incident data: of 21 well-known supply chain incidents, 11 could have been blocked by a 7-day gate. More than half of known incidents can be prevented with a single line of configuration.
| Incident | Year | Ecosystem | Window of exposure | 7-day gate |
|---|---|---|---|---|
| axios | 2026 | npm | ~4 hours | Blocked |
| Trivy-Action | 2026 | GitHub Actions | ~12 hours | Blocked |
| Nx / S1ngularity | 2025 | npm | ~1 day | Blocked |
| Gluestack / React Native ARIA | 2025 | npm | A few days | Blocked |
| tj-actions/changed-files | 2025 | GitHub Actions | ~3 days | Blocked |
| reviewdog/action-setup | 2025 | GitHub Actions | ~2 hours | Blocked |
| Ultralytics YOLO | 2024 | PyPI | ~1–2 days | Blocked |
| Solana web3.js | 2024 | npm | ~5 hours | Blocked |
| Polyfill.io | 2024 | CDN | ~4 months | Not blocked |
| XZ Utils | 2024 | OS packages | 2+ years | Not blocked |
| Ledger Connect Kit | 2023 | npm | ~5 hours | Blocked |
| 3CX | 2023 | Desktop app | Several weeks | Not blocked |
| PyTorch torchtriton | 2022 | PyPI | ~5 days | Blocked |
| node-ipc | 2022 | npm | Weeks+ | Not blocked |
| colors / faker | 2022 | npm | Days to weeks | Partially blocked |
| Log4Shell | 2021 | Java | N/A | Not blocked |
| ua-parser-js | 2021 | npm | ~4 hours | Blocked |
| Codecov | 2021 | SaaS | ~2 months | Not blocked |
| Dependency Confusion (Alex Birsan) | 2021 | Multiple | Varies | Partially blocked |
| SolarWinds | 2020 | Build system | ~9 months | Not blocked |
| event-stream | 2018 | npm | ~2 months | Not blocked |
Partially blocked means only some stages of the attack can be prevented (for example, exposure in the first few days is blocked but subsequent stages are not). A simple count gives: 11 blocked / 8 not blocked / 2 partially blocked.
One more observation from the table: every “not blocked” incident directly reflects a fundamental limitation of the 7-day gate. Long-term infiltrations like XZ Utils, SolarWinds, and event-stream with windows lasting months or years; attacks outside the npm registry like Polyfill.io and Codecov; vulnerabilities in otherwise legitimate code like Log4Shell — all of these fall outside what cooldown can address. These limitations are covered in detail below.
Extending to 14 or 30 days blocks a few more incidents, but comes at the cost of delaying legitimate security patches. The current industry consensus is that 7 days strikes a reasonable balance.
What Attacks Can It Block?
The 7-day gate is effective against:
1. Maintainer Account Hijacks
The most common type, and the fastest to be detected. The axios case from Part 1 is a prime example. The cycle from hijack to malicious publish to detection to removal typically completes within 24 hours, so the 7-day gate blocks nearly all of them.
2. Typosquatting
Fake packages with names similar to popular ones — like react-doom — designed to be installed by accident. These are caught by automated scanners shortly after publication and taken down within a few days.
3. Dependency Confusion
Uploading a package with the same name as an internal private package to the public registry, tricking the build system into fetching the wrong one. These also follow the pattern of being discovered and removed quickly.
4. Fast Dependency Injection
Like plain-crypto-js in the axios case — a compromised package adding a newly published malicious package as a new dependency. The key detail is that the injected dependency is itself a brand-new package. The 7-day gate blocks both the new version of the compromised main package and the new dependency it pulls in.
What Attacks Can It Not Block?
When evaluating a defense strategy, the more important question is “what does it fail to stop?” The 7-day gate is ineffective against:
1. Long-Term Infiltration — The XZ Utils Pattern
The XZ Utils backdoor discovered in 2024 was the result of an attacker spending two years building trust as a maintainer before inserting a backdoor. The backdoor was delivered through a normal official release and went undetected for months.
The 7-day gate blocks “just-published” versions, but it is powerless against a version that has been in the registry for months and is considered legitimate.
2. Deliberate Maintainer Sabotage
As with colors.js (2022) and node-ipc (2022), a maintainer can intentionally insert malicious code. In those cases, the code goes through a normal release process. The 7-day gate provides some protection in the first few days, but if a maintainer deliberately moves slowly, the attack passes through the gate after it opens.
3. Build System Compromise
Incidents like SolarWinds (2020) and 3CX (2023) involved the build system itself being compromised, not the package registry. Backdoors were embedded in build artifacts while normal version numbers and normal release procedures were used. Package manager-level defenses cannot reach this.
4. Attacks Outside the Registry
Codecov (2021) involved a shell script downloaded in CI being tampered with. Polyfill.io (2024) was a CDN attack where a domain acquisition led to malicious JavaScript being served. Neither entered through the npm gate.
5. Vulnerabilities in Legitimate Code
Like Log4Shell: a security flaw in code written without malicious intent. This is not a supply chain attack — it is a conventional vulnerability. The correct response here is actually to patch quickly. The 7-day gate is a disadvantage in this case.
| Attack type | 7-day gate effectiveness |
|---|---|
| Maintainer account hijack | Very effective |
| Typosquatting | Very effective |
| Dependency confusion | Very effective |
| Fast dependency injection | Very effective |
| Long-term infiltration (XZ Utils pattern) | Ineffective |
| Maintainer sabotage | Limited |
| Build system compromise | Ineffective |
| Outside the registry (CDN, scripts) | Ineffective |
| Vulnerabilities in legitimate libraries | Counter-productive |
The Cost of the Defense
The reason this defense is described as “simple and effective” is that it costs almost nothing.
| Cost item | Level |
|---|---|
| Configuration changes | A few lines in config files |
| Learning curve | Virtually none |
| CI/CD pipeline changes | Replacing --frozen-lockfile with --immutable for Yarn 4 |
| Delay in receiving legitimate patches | Average 7 days (security alerts are immediate) |
| Operational overhead | Minimal (Dependabot handles it automatically) |
The largest cost is “receiving legitimate new versions 7 days later.” Even that is minimal in practice, since security alerts bypass the cooldown entirely.
As One Layer in Defense-in-Depth
The core point is that this strategy is not a silver bullet — and should not be expected to be one. The 7-day gate is a time-based filter designed around the fast-detection/removal pattern. As shown above, long-term infiltrations, build system compromises, and off-registry attacks all require different defensive tools.
Defense-in-depth means not relying on any single strong defense, but layering multiple defenses with different characteristics. When one layer fails to stop an attack, the next layer catches it. Cooldown is just one layer in that stack.
Other defenses that pair well with cooldown:
| Defense | Attacks it covers |
|---|---|
enableScripts: false | Immediate RCE via postinstall |
| GitHub Actions SHA pinning | Tampering with Actions themselves |
| Hardened Mode (Yarn 4) | Lockfile tampering |
| OIDC / signed publish | Unofficial publication paths |
| SBOM management | Dependency visibility |
| Automated security scanners | Known CVEs and malicious patterns |
| Code review | Deliberate sabotage (attention to dependency changes) |
| CDN integrity (SRI) | External asset tampering outside the registry |
The three strategies from Part 2 cover a portion of this table. The rest can be introduced incrementally based on each project’s needs.
Conclusion
To summarize the series:
- Part 1: npm’s trust model is structurally exposed to attack, and the
axioscase showed that malicious versions do exist — even if their window is very short. - Part 2: GitHub Actions SHA pinning, Dependabot cooldown, and Yarn’s
npmMinimalAgeGatelet you naturally sidestep that exposure window in a real-world project. - Part 3 (this article): A simple time-based gate can block a significant fraction of known supply chain incidents, but it is not comprehensive — it must be combined with other defenses.
Supply chain security is inherently a domain where there is no single definitive solution. You cannot audit every dependency yourself, and you cannot verify the intentions of every maintainer. That is precisely why “simple defenses with almost no cost” shine so brightly. Setting one number — 7 days — in a few lines of configuration can block more than half of known supply chain attacks. In the security domain, that kind of return on investment is remarkably rare.
If your project does not yet have a cooldown or minimum release age gate, now is the best time to add one.
References
Was my blog helpful? Please leave a comment at the bottom. it will be a great help to me!
App promotion
Deku.Deku created the applications with Flutter.If you have interested, please try to download them for free.