Supply Chain Security: Implementing Cooldown Phases for Dependencies
Created:
Introduction
Supply chain attacks have emerged as a critical threat in modern software development, exploiting trust in third-party dependencies, CI/CD pipelines, and package managers. These attacks can inject malicious code into widely used libraries, compromising thousands of projects before detection.
One of the most effective defenses is implementing cooldown phases for dependencies-delaying the installation of newly published packages until they have been available for a minimum period. This allows time for security reviews and reduces the risk of immediate compromise.
This article explains:
- What supply chain attacks are and how they work.
- How cooldown phases mitigate these risks.
- Practical steps to implement cooldowns across npm, pnpm, Bun, Yarn, pip, uv, and RubyGems.
- Additional strategies and tools to harden your supply chain security.
Understanding Supply Chain Attacks
Mechanisms and Vectors
Supply chain attacks target the trust relationships between software suppliers and consumers. Common attack vectors include:
| Vector | Description |
|---|---|
| Third-Party Dependencies | Attackers compromise widely used libraries, injecting malware that inherits trust from the host. |
| CI/CD Pipelines | Compromised build pipelines inject malware during automated builds. |
| Insider Threats | Malicious actors with legitimate access introduce vulnerabilities or backdoors. |
| Man-in-the-Middle | Interception of code or updates during transmission enables tampering. |
Real-World Examples
Recent high-profile supply chain attacks include:
1. NotPetya (2017-06)
- Year: June 27, 2017
- Impact: $10B+ in global damages. Wiper malware disguised as ransomware, targeting Ukrainian organizations via compromised M.E.Doc accounting software. Spread globally, affecting Maersk ($300M), Merck ($870M), FedEx ($400M), and others.
- Vector: Supply chain (software update).
- Sources:
2. SolarWinds (2020-12)
- Year: 2020 (compromise began as early as September 2019; discovered December 2020)
- Impact: Backdoor distributed to ~18,000 customers, including U.S. government agencies (Treasury, DHS, DoD, etc.).
- Vector: Compromised update mechanism (SUNBURST malware).
- Sources:
3. Kaseya (2021-07)
4. 3CX (2023-03)
- Year: March 2023 (initial compromise via X_TRADER; public disclosure on March 29–30, 2023)
- Impact: First confirmed "double supply chain attack": Initial compromise via Trading Technologies' X_TRADER software, then 3CX's own software was weaponized. 600,000+ customers potentially exposed to malware.
- Vector: Compromised dependency (X_TRADER → 3CXDesktopApp).
- Sources:
5. MOVEit (2023-05/06)
- Year: May–June 2023
- Impact: Zero-day SQL injection (CVE-2023-34362) exploited by Cl0p ransomware group. 2,500+ organizations and 66M+ individuals affected (as of Oct 2023). High-profile victims: BBC, British Airways, U.S. Dept. of Energy, Nova Scotia (100K employees).
- Vector: Vulnerable third-party component (MOVEit Transfer).
- Sources:
6. Axios (2026-03)
- Year: March 31, 2026
- Impact: Two malicious versions (1.14.1 and 0.30.4) published to npm, injecting a cross-platform Remote Access Trojan (RAT) via a dependency (plain-crypto-js@4.2.1). 100M+ weekly downloads of Axios; exposure window: ~3 hours.
- Vector: Compromised npm package (maintainer account takeover).
- Sources:
7. Bitwarden CLI (2026-04)
- Year: April 22, 2026
- Impact: Malicious @bitwarden/cli@2026.4.0 available on npm for ~90 minutes (5:57–7:30 PM ET). Self-propagating worm stole cloud credentials, GitHub tokens, SSH keys, and AI tooling secrets (e.g., Claude, Cursor). Linked to Checkmarx supply chain breach.
- Vector: Compromised dependency (CI/CD pipeline hijack).
- Sources:
8. TanStack (2026-05)
- Year: May 11, 2026
- Impact: 84 malicious versions across 42 @tanstack/ packages (e.g., @tanstack/router). Part of the "Mini Shai-Hulud" worm campaign. Attack chained GitHub Actions vulnerabilities (cache poisoning, OIDC token theft). 12M+ weekly downloads for @tanstack/react-router.
- Vector: Compromised npm packages (CI/CD pipeline abuse).
- Sources:
Cooldown Phases: A Critical Defense Mechanism
How Cooldowns Work
A cooldown phase delays the installation of newly released packages until they have been available for a minimum period (e.g., 7 days). This provides a window for:
- Security researchers to detect malicious packages.
- Automated tools to flag suspicious activity.
- Package maintainers to yank (remove) compromised versions.
Example Workflow:
- A package version is published to a registry (e.g., npm, PyPI).
- The package manager enforces a minimum release age (e.g., 7 days).
- You hope that any malicious package will be detected and removed before it can be installed.
Effectiveness
- Most attacks are detected within hours of release.
- A 7-day cooldown would have blocked the majority of recent supply chain attacks (e.g., Bitwarden CLI, TanStack, Axios).
- Converts immediate risk into a human-manageable timeframe.
Implementing Cooldowns Across Package Managers
npm
Configuration:
- File:
~/.npmrcor project.npmrc - Setting:
min-release-age(in days) - Example:
min-release-age=7
ignore-scripts=true
- Override (for trusted packages):
npm install <package> --min-release-age 0pnpm
Configuration:
- File:
~/.config/pnpm/rcorpnpm-workspace.yaml - Setting:
minimum-release-age(in minutes) - Example:
minimum-release-age: 10080 # 7 days
minimum-release-age-exclude:
- "@trusted/*"
- Override:
pnpm add <package> --minimum-release-age 0
- Default: Since pnpm v11, the default cooldown is 1 day (1440 minutes).
Additional Security Features:
block-exotic-subdeps=true(blocks dependencies not in the lockfile).trust-policy=low(restricts untrusted registries).
Source: pnpm Supply Chain Security
Bun
Configuration:
- File:
~/.bunfig.toml - Setting:
minimumReleaseAge(in seconds) - Example:
[install]
minimumReleaseAge = 604800 # 7 days
- Override:
bun add <package> --minimum-release-age 0Yarn
Configuration:
- File:
.yarnrc.yml - Setting:
npmMinimalAgeGate(in minutes) - Example:
npmMinimalAgeGate: 10080 # 7 days
npmPreapprovedPackages:
- typescript
- eslint
- Override: Not directly supported (use
resolutionsorversionconstraints).
Python (uv and pip)
uv
- Command-line flag:
uv pip install --exclude-newer "7 days"
- Override:
uv pip install --exclude-newer "0 days"pip
- Absolute timestamp (older pip versions):
pip install --uploaded-prior-to 2026-05-13
- Relative duration (pip 26.1+):
pip install --uploaded-prior-to "7 days"
- Override:
pip install --uploaded-prior-to "0 days"
Source: pip Documentation
RubyGems
- Native Support: None (as of May 2026).
- Community Solution:
- Use gem.coop (a registry that enforces a 48-hour cooldown for Bundler users).
- Configure Bundler to use
gem.coop:
source "https://gem.coop"Broader Strategies for Preventing Supply Chain Attacks
| Strategy | Description | Tools/Implementation |
|---|---|---|
| Verify Package Integrity | Use checksums and cryptographic signatures to ensure packages haven’t been tampered with. | npm ci, pnpm audit, pip hash |
| Signed Packages | Enforce digital signatures on artifacts to confirm authenticity. | Sigstore, Cosign, GitHub Sigstore |
| Audit Dependencies | Regularly scan for vulnerabilities in dependencies and transitive dependencies. | npm audit, pnpm audit, GitHub Dependabot |
| Pin Versions | Commit lockfiles (package-lock.json, yarn.lock, Gemfile.lock) to prevent unexpected updates. | npm ci, pnpm install --frozen-lockfile |
| Zero-Trust Architecture | Treat all third-party code as untrusted until verified. | Network segmentation, least privilege access |
| CI/CD Security | Secure build pipelines with access controls, secrets management, and monitoring. | GitHub Actions, GitLab CI, CircleCI |
| SBOM (Software Bill of Materials) | Maintain an inventory of all components to quickly identify and remediate vulnerabilities. | Syft, Dependency-Track, GitHub SBOM |
| Automated Scanning | Integrate SAST, SCA, and secrets scanning into CI/CD. | Snyk, Dependabot, GitHub Advanced Security |
| Incident Response Plans | Develop and test procedures for responding to supply chain compromises. | Custom playbooks, GitHub Security Advisories |
Tools and Services to Enhance Supply Chain Security
| Tool/Service | Key Features | How It Helps |
|---|---|---|
| DepsGuard | Scans and fixes package manager configs (npm, pnpm, Yarn, Bun, uv). Zero dependencies. | Automates cooldown enforcement and security settings. |
| StepSecurity | GitHub PR check that fails PRs introducing npm packages released within a configurable cooldown. | Prevents introduction of fresh malicious packages. |
| OpenRewrite | Automates adding cooldown sections to Dependabot config files. | Ensures dependency update tools respect cooldown policies. |
| Dependabot | Configurable cooldowns by semantic version type (e.g., ignore: [{ dependency-name: "*", versions: ["< 7 days"] }]). | Manages dependency updates with security delays. |
| Renovate | Supports minimumReleaseAge with human-readable durations (e.g., "7 days"). Default: 3 days for npm. | Automates dependency updates with cooldowns. |
| pnpm 11+ | Built-in minimumReleaseAge, blockExoticSubdeps, and trustPolicy settings. | Enforces cooldowns and restricts untrusted dependency sources. |
| npm ci | Prevents builds from pulling new versions not in the lockfile. | Maintains build integrity in CI/CD pipelines. |
| GitHub Actions | Supports cooldown checks, secrets scanning, and dependency review. | Detects compromised packages and prevents unauthorized access. |
Comparative Table of Cooldown Configurations
| Package Manager | Config File | Setting Name | Unit | Default Cooldown | Override Command | Exclusions |
|---|---|---|---|---|---|---|
| npm | ~/.npmrc | min-release-age | Days | None | npm install <pkg> --min-release-age 0 | None (as of May 2026) |
| pnpm | ~/.config/pnpm/rc | minimum-release-age | Minutes | 1 day (1440 min) | pnpm add <pkg> --minimum-release-age 0 | minimum-release-age-exclude |
| Bun | ~/.bunfig.toml | minimumReleaseAge | Seconds | None | bun add <pkg> --minimum-release-age 0 | None |
| Yarn | .yarnrc.yml | npmMinimalAgeGate | Minutes | None | Not supported | npmPreapprovedPackages |
| uv (Python) | Command-line | --exclude-newer | Relative (e.g., 7d) | None | uv pip install --exclude-newer "0 days" | None |
| pip (Python) | Command-line | --uploaded-prior-to | Absolute/Relative | None | pip install --uploaded-prior-to "0 days" | None |
| RubyGems | Registry-level (gem.coop) | N/A | N/A | 48 hours | Not applicable | Not applicable |
Conclusion
Supply chain attacks are a growing and severe threat to software development, but cooldown phases provide a simple yet powerful defense. By delaying the installation of newly released packages, developers gain critical time to detect and mitigate malicious releases.
Key Takeaways
- Implement cooldowns in your package managers (npm, pnpm, Bun, Yarn, pip, uv, RubyGems).
- Combine cooldowns with other security measures:
- Verify package integrity (signatures, checksums).
- Audit dependencies regularly.
- Pin versions and commit lockfiles.
- Secure CI/CD pipelines.
- Adopt zero-trust principles.
- Use automation tools like DepsGuard, StepSecurity, and OpenRewrite to enforce cooldowns and audit configurations.
- Stay informed about supply chain threats and best practices (e.g., cooldowns.dev).
Call to Action
- Start today: Add a 7-day cooldown to your projects.
- Educate your team: Share this guide and discuss supply chain risks.
- Contribute: Report malicious packages and support open-source security initiatives.
By adopting these practices, you can significantly reduce the risk of supply chain compromises and build more secure software.
References
- Cooldowns.dev
- pnpm Supply Chain Security
- DepsGuard
- StepSecurity
- OpenRewrite
- GitHub Supply Chain Security
Feedback
Have thoughts or experiences you'd like to share? I'd love to hear from you! Whether you agree, disagree, or have a different perspective, your feedback is always welcome. Drop me an email and let's start a conversation.