Back to Blog
high SEVERITY8 min read

How Dependabot Missing Cooldown happens in GitHub Actions and how to fix it

A Dependabot configuration in `.github/dependabot.yml` was missing cooldown periods for both its npm and GitHub Actions package ecosystems, meaning newly published — potentially malicious or unstable — package versions could be proposed for adoption immediately after release. Adding a `cooldown` block with `default-days: 7` to each ecosystem entry creates a 7-day buffer, allowing the security community time to identify and flag compromised packages before they reach your codebase.

O
By Orbis AppSec
Published August 26, 2026Reviewed August 26, 2026

Answer Summary

A missing Dependabot cooldown period (CWE-1104: Use of Unmaintained Third-Party Components) in `.github/dependabot.yml` meant that newly published npm and GitHub Actions packages could be automatically proposed for adoption the moment they appeared on the registry — with no waiting period for the security community to vet them. The fix adds a `cooldown` block with `default-days: 7` to both the `npm` and `github-actions` ecosystem entries, introducing a 7-day delay before Dependabot proposes updates to freshly published package versions.

Vulnerability at a Glance

cweCWE-1104 (Use of Unmaintained Third-Party Components)
fixAdded `cooldown: default-days: 7` to both ecosystem entries to enforce a 7-day waiting period before updates are proposed
riskAutomatic adoption of newly published malicious or unstable packages before the security community can react
languageYAML (GitHub Actions / Dependabot configuration)
root causeNo `cooldown` block defined in either the `npm` or `github-actions` package-ecosystem entries in `.github/dependabot.yml`
vulnerabilityDependabot Missing Cooldown Period

How Dependabot Missing Cooldown Happens in GitHub Actions and How to Fix It

Introduction

The .github/dependabot.yml file is the heartbeat of automated dependency management for millions of GitHub repositories. It tells Dependabot which package ecosystems to watch, how often to check for updates, and how to label the resulting pull requests. But a subtle misconfiguration — one that is easy to overlook — can quietly expose a Node.js project and all of its downstream consumers to supply chain attacks: the absence of a cooldown period.

In this repository's Dependabot configuration, both the npm and github-actions ecosystem entries were configured to check for updates on a weekly schedule with no restriction on how new a package version could be before Dependabot proposed it. That means a package published at 9:00 AM on Monday could appear in an automated pull request by the next scheduled run — before a single security researcher has had a chance to flag it as compromised.


The Vulnerability Explained

What the original configuration looked like

Before the fix, the relevant portion of .github/dependabot.yml (starting at line 3) looked like this:

# .github/dependabot.yml (before fix)
updates:
  - package-ecosystem: 'npm'
    directory: '/'
    schedule:
      interval: 'weekly'
    labels:
      - 'dependencies'
      - 'skip changeset'

  - package-ecosystem: 'github-actions'
    directory: '/'
    schedule:
      interval: weekly
    labels:
      - 'dependencies'
      - 'skip changeset'

Neither the npm entry nor the github-actions entry contains a cooldown block. This is the exact pattern that the Semgrep rule package_managers.dependabot.dependabot-missing-cooldown.dependabot-missing-cooldown matched at line 3 of the file.

Why the absence of a cooldown is dangerous

When Dependabot has no cooldown configured, it will propose an update to a package version as soon as that version appears on the registry (subject only to the check schedule). This creates a critical window of risk rooted in how supply chain attacks actually work:

  1. Typosquatting and account takeovers: An attacker publishes a malicious version of a popular package (or hijacks a maintainer's npm account) and pushes a backdoored release. With no cooldown, Dependabot opens a PR within days.
  2. Dependency confusion attacks: A malicious package with the same name as an internal package is published to the public registry. Dependabot immediately surfaces it.
  3. Unstable releases: A maintainer accidentally publishes a broken version. Without a cooldown, that broken version is proposed before it can be yanked or patched.

Because this is a Node.js library, the blast radius extends beyond this repository. Downstream consumers who depend on this package could inherit a compromised transitive dependency if a malicious update were merged without adequate review time.

A concrete attack scenario

Imagine an attacker compromises the npm credentials of a maintainer for a popular utility package that this project depends on. At 2:00 AM UTC, the attacker publishes version 3.4.1 containing a credential-harvesting script. Without a cooldown, Dependabot's next weekly run generates a pull request titled "Bump utility-package from 3.4.0 to 3.4.1." A developer, seeing only a minor patch bump and a green CI run (the malicious code may not trigger tests), merges the PR. The security community does not flag the compromised version until 36 hours later — too late for this project.

A 7-day cooldown would have meant that 3.4.1 was never even proposed until day 7, by which time the npm security team would have unpublished the malicious version and the community would have issued warnings.


The Fix

The fix is four lines of YAML — two lines added to each ecosystem entry — but the security impact is significant.

Before and after

Before (vulnerable):

  - package-ecosystem: 'npm'
    directory: '/'
    schedule:
      interval: 'weekly'
    labels:
      - 'dependencies'
      - 'skip changeset'

After (fixed):

  - package-ecosystem: 'npm'
    directory: '/'
    schedule:
      interval: 'weekly'
    cooldown:
      default-days: 7
    labels:
      - 'dependencies'
      - 'skip changeset'

The same cooldown block was added to the github-actions ecosystem entry:

Before (vulnerable):

  - package-ecosystem: 'github-actions'
    directory: '/'
    schedule:
      interval: weekly
    labels:
      - 'dependencies'
      - 'skip changeset'

After (fixed):

  - package-ecosystem: 'github-actions'
    directory: '/'
    schedule:
      interval: weekly
    cooldown:
      default-days: 7
    labels:
      - 'dependencies'
      - 'skip changeset'

Why both ecosystems needed the fix

It is important to note that both the npm and github-actions entries were updated. GitHub Actions workflows are themselves a supply chain attack surface: a compromised Action (e.g., a hijacked actions/checkout or a third-party Action) could exfiltrate secrets, modify build artifacts, or inject malicious code into your CI pipeline. The same 7-day cooldown logic applies equally to both ecosystems.

What default-days: 7 actually does

The cooldown.default-days setting instructs Dependabot to ignore any package version that was published fewer than 7 days ago. It will continue to monitor for updates, but it will not open a pull request for a version until that version has been publicly available for at least a week. This gives:

  • The npm security team and community time to review and flag malicious releases
  • Automated security scanners (Snyk, OSV, GitHub Advisory Database) time to index new vulnerabilities
  • The package maintainer time to yank or patch a bad release before it propagates

You can increase this value beyond 7 days for higher-risk ecosystems or reduce it for ecosystems with more trusted supply chains — but 7 days is the widely recommended baseline.


Key Takeaways

  • Both ecosystem entries in dependabot.yml lacked a cooldown block — the npm entry at the top of the file and the github-actions entry below it were both vulnerable, meaning the CI pipeline and the runtime dependencies were equally exposed.
  • A 7-day cooldown is not just a best practice — it is a concrete defense against the "zero-day publish" attack vector, where a malicious package version is proposed before the security community can react.
  • GitHub Actions are a supply chain attack surface too — the github-actions ecosystem entry needed the same fix as npm; compromised Actions can exfiltrate CI secrets and tamper with build artifacts.
  • This Node.js library's downstream consumers were also at risk — because the project is a library, any malicious transitive dependency merged here could propagate to every application that installs this package.
  • Static analysis (Semgrep) can detect this configuration gap automatically — the rule package_managers.dependabot.dependabot-missing-cooldown.dependabot-missing-cooldown matched this pattern at line 3 of the file, demonstrating that YAML-level security misconfigurations are tractable to automated tooling.

How Orbis AppSec Detected This

  • Source: The updates entries in .github/dependabot.yml (lines 3 and 11) define the package ecosystems Dependabot monitors. Without a cooldown block, any newly published package version immediately becomes a candidate for an automated PR.
  • Sink: Dependabot's version update engine — which opens pull requests proposing dependency upgrades — is the "sink" here. Without a cooldown gate, it will surface versions published seconds ago.
  • Missing control: The cooldown block (specifically default-days: 7) was entirely absent from both the npm and github-actions ecosystem entries, meaning there was no minimum-age requirement for proposed package versions.
  • CWE: CWE-1104 — Use of Unmaintained Third-Party Components (the broader category that encompasses unvetted dependency adoption).
  • Fix: A cooldown: default-days: 7 block was inserted into both the npm and github-actions entries in .github/dependabot.yml, enforcing a 7-day minimum age for any package version before Dependabot proposes it.

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

A missing cooldown period in dependabot.yml is easy to overlook — it is an absence of configuration rather than a piece of obviously wrong code. But for a Node.js library with downstream consumers, it represents a real and exploitable gap in supply chain security. The fix is minimal: four lines of YAML across two ecosystem entries. The protection it provides — a 7-day window for the security community to vet newly published packages before they are proposed for adoption — is disproportionately large relative to the effort.

The next time you configure Dependabot for a new repository, make cooldown: default-days: 7 part of your standard template. And consider running Semgrep's Dependabot ruleset in CI to ensure that this control is never accidentally removed.


Prevention and further reading

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #607

Related Articles

high

How Denial of Service via Infinite Loop Happens in JavaScript Dependencies and How to Fix It

CVE-2026-67213 is a high-severity denial of service vulnerability in nanoid before version 5.1.6 that triggers an infinite loop during random ID generation when processing specially crafted input. We upgraded nanoid across the entire dependency tree to patch this flaw and prevent attackers from freezing application threads. This fix ensures that ID generation remains resilient even when handling adversarial input patterns.

high

How Sensitive Data Exposure happens in Zotero plugins and how to fix it

A high-severity data exposure vulnerability in `Zotero.ts` automatically transmitted complete document metadata—including private notes, attachment paths, and tags—to external LLM services without user consent. The fix replaces broad `item.toJSON()` serialization with explicit field selection, sending only essential bibliographic data.

high

How missing dependency update cooldowns happen in GitHub Dependabot configurations and how to fix it

A semgrep scan flagged `.github/dependabot.yml` for lacking a cooldown period, meaning Dependabot would immediately propose updates to brand-new package versions across npm, Bundler, and Docker ecosystems. The fix adds a `cooldown: default-days: 7` block to every `package-ecosystem` entry, forcing a one-week waiting period before newly published releases are considered — reducing exposure to malicious or unstable package drops.

high

How Path Traversal Happens in TensorFlow's Data Service and How to Fix It

TensorFlow's data service dispatcher validated dataset IDs against forward-slash traversal attacks but overlooked backslash characters on non-Windows platforms, allowing attackers to escape the root directory. A targeted fix adds explicit backslash validation across all platforms, closing a high-severity path traversal vulnerability in the snapshot management system.

critical

How Unbounded WebSocket Message Handling Causes Resource Exhaustion in Node.js and How to Fix It

The WebSocketCrossServerAdapter class in a popular Node.js WebSocket library lacked any rate limiting on inbound messages, allowing attackers to flood Redis nodes and WebSocket servers with high-volume traffic. The fix introduces a configurable `rateLimit` option that caps messages per connection per second, preventing resource exhaustion while preserving legitimate functionality.

critical

How Remote Code Execution Happens in Handlebars Template Compilation and How to Fix It

CVE-2026-33937 is a critical remote code execution vulnerability in Handlebars.js that allows attackers to execute arbitrary code by passing maliciously crafted Abstract Syntax Tree (AST) objects to the compile() function. The vulnerability was patched in version 4.7.9, and we've upgraded to protect against this threat vector.