How Dependabot Missing Cooldown Happens in Node.js and How to Fix It
In a Node.js documentation site repository, a high-severity supply chain risk was found hiding in plain sight — not in application code, but in a two-line Dependabot configuration file. The .github/dependabot.yml file was missing a cooldown block, meaning Dependabot would immediately propose updates to any newly published npm package version, including potentially malicious ones.
This kind of misconfiguration is easy to overlook because it doesn't look like a bug. The config file is syntactically valid, Dependabot runs correctly, and PRs are opened on schedule. But the absence of a single configuration block quietly removes a critical safety buffer between your project and the broader npm supply chain.
The Vulnerability Explained
What the Vulnerable Configuration Looked Like
Here's the .github/dependabot.yml as it existed before the fix:
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "monthly"
This configuration tells Dependabot to check for npm updates monthly. That sounds reasonable — but there's a subtle and dangerous gap. The schedule.interval controls when Dependabot looks for updates. It does not control how recently a package version was published before Dependabot proposes it.
If an attacker publishes a malicious version of a popular package on, say, the 28th of the month, and Dependabot runs its monthly check on the 29th, that malicious version would be proposed as an update within 24 hours of publication — long before the security community has had a chance to analyze it, flag it, or issue an advisory.
The Specific Risk: Newly Published Packages
The npm ecosystem has experienced a significant number of supply chain attacks in recent years. The attack pattern is consistent:
- An attacker compromises a maintainer's account, or publishes a typosquat package
- A malicious version is published to the npm registry
- Automated dependency update tools (like Dependabot) immediately propose the new version
- A developer merges the PR without deep scrutiny, assuming automated tools are safe
- The malicious package executes in CI, in build tooling, or in production
The docs-site/package-lock.json file — explicitly called out in this vulnerability report — reflects the npm dependency tree for the documentation site. Documentation sites often have broad dependency trees with many transitive dependencies, each of which represents a potential attack surface.
Why This Matters for This Specific Project
This is a Node.js library repository. Vulnerabilities in the build and documentation toolchain don't just affect the maintainers — they affect every downstream consumer who clones, forks, or mirrors the repository. A compromised build tool could, for example, inject malicious code into published package artifacts, affecting every project that installs this library.
The Fix
The fix is minimal but meaningful. Here's the exact diff applied to .github/dependabot.yml:
Before:
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "monthly"
After:
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "monthly"
cooldown:
default-days: 7
What the cooldown Block Does
The cooldown block, introduced in GitHub's Dependabot configuration schema, instructs Dependabot to only propose updates for package versions that have been publicly available for at least default-days days. With default-days: 7, a package version published today will not appear in a Dependabot PR until it has been available on the registry for a full week.
This 7-day window is significant because:
- Security researchers monitor the npm registry continuously and typically flag malicious packages within hours to days
- CVE databases and GitHub Advisory Database are usually updated within days of a confirmed compromise
- Community scrutiny — download spikes, unusual changelogs, and new maintainer accounts — becomes visible within the first week
- Automated malware scanning services integrated with the npm registry have time to process and flag suspicious packages
The Two-Line Change That Matters
cooldown:
default-days: 7
These two lines, added at the correct indentation level under the npm package-ecosystem entry, are all it takes. The change is scoped entirely to .github/dependabot.yml and has no effect on application behavior, test results, or the published package itself.
Prevention & Best Practices
1. Always Include cooldown in Dependabot Configurations
Every package-ecosystem entry in your dependabot.yml should include a cooldown block. If you manage multiple ecosystems (e.g., npm, docker, github-actions), each needs its own cooldown:
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
cooldown:
default-days: 7
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
cooldown:
default-days: 7
2. Consider Higher Cooldown Values for Production Dependencies
For packages that ship directly to end users, consider default-days: 14 or even default-days: 30. The GitHub Dependabot documentation also supports per-dependency overrides if you need finer control.
3. Enable Dependabot Security Alerts Separately
The cooldown block applies to version updates, not security updates. If a known vulnerability is patched in a new version, Dependabot security alerts can still propose that update promptly. This is the correct behavior — you want fast patches for known CVEs, but a delay for routine version bumps.
4. Use Semgrep to Enforce This in CI
The Semgrep rule package_managers.dependabot.dependabot-missing-cooldown.dependabot-missing-cooldown can be added to your CI pipeline to catch this misconfiguration before it reaches your main branch:
semgrep --config "p/default" .github/dependabot.yml
5. Combine with allow and ignore Lists
Reduce your attack surface further by explicitly allowing only the package types you need:
allow:
- dependency-type: "direct"
This prevents Dependabot from automatically proposing transitive dependency updates, which are harder to review and represent a larger attack surface.
Relevant Standards
- CWE-1357: Reliance on Insufficiently Trustworthy Component
- OWASP A06:2021: Vulnerable and Outdated Components
- SLSA (Supply Chain Levels for Software Artifacts): Recommends provenance verification and controlled update processes
Key Takeaways
- The
schedule.intervalin Dependabot does not protect you from newly published malicious packages — it only controls when checks run, not how old a version must be before it's proposed. docs-site/package-lock.jsonrepresents a real attack surface: documentation site dependencies can include build tools that, if compromised, could affect published package artifacts.- Two lines of YAML (
cooldown: default-days: 7) provide a week-long safety buffer against the most common supply chain attack pattern: publish-and-wait-for-automerge. - Monthly update schedules create a false sense of security: a malicious package published the day before a monthly run is just as dangerous as one proposed in real time, without a cooldown.
- Static analysis tools like Semgrep can catch this class of misconfiguration automatically, making it feasible to enforce cooldown policies across all repositories in an organization.
How Orbis AppSec Detected This
- Source: The
.github/dependabot.ymlfile at line 3, where thenpmpackage-ecosystementry begins — this is where Dependabot's update behavior is configured, and where the missingcooldownblock creates the exposure. - Sink: The absence of a
cooldownblock means any newly published npm package version flows directly into Dependabot's proposed update queue with no delay, makingdocs-site/package-lock.jsona potential landing zone for malicious packages. - Missing control: No
cooldownblock under thenpmpackage-ecosystementry; Dependabot had no instruction to wait before proposing updates to recently published versions. - CWE: CWE-1357 — Reliance on Insufficiently Trustworthy Component
- Fix: Added
cooldown: default-days: 7under thenpmpackage-ecosystementry in.github/dependabot.yml, introducing a mandatory 7-day waiting period before any newly published package version is proposed as an update.
Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.
Conclusion
Supply chain attacks targeting the npm ecosystem are not theoretical — they are an active and growing threat. The missing cooldown block in this project's .github/dependabot.yml was a small configuration gap with potentially large consequences: any malicious package published to npm could have been proposed as an automated update within hours, before the security community had time to respond.
The fix — two lines of YAML — introduces a 7-day safety buffer that aligns with real-world security response timelines. It costs nothing in terms of security patch velocity (Dependabot security alerts remain unaffected) and gains a meaningful reduction in supply chain risk.
If you maintain Node.js projects with Dependabot enabled, audit your dependabot.yml files today. Look for any package-ecosystem entry that lacks a cooldown block, and add one. It's one of the highest-value, lowest-effort security improvements you can make to your CI/CD pipeline.