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.


Prevention & Best Practices

1. Always define cooldown for every ecosystem entry

Any updates entry in dependabot.yml without a cooldown block is a potential supply chain risk. Treat the absence of cooldown the same way you would treat the absence of input validation: a missing control, not a safe default.

# Recommended baseline for any ecosystem
cooldown:
  default-days: 7

2. Use semver-specific cooldowns for major versions

Dependabot's cooldown configuration also supports per-semver-type overrides. You might want a longer cooldown for major version bumps, which carry higher risk of breaking changes or supply chain tampering:

cooldown:
  default-days: 7
  semver-major-days: 14   # Extra caution for major bumps

3. Combine cooldown with allow and ignore rules

Cooldown is one layer of defense. Pair it with explicit allow lists (only update packages you explicitly approve) and ignore rules for packages that require manual review:

allow:
  - dependency-type: 'direct'
cooldown:
  default-days: 7

4. Enable Dependabot security alerts alongside version updates

Version update cooldowns protect against newly published malicious packages. Dependabot security alerts (configured separately via dependabot_security_updates) respond to known CVEs and should remain unrestricted by cooldown so that critical patches are not delayed.

5. Use static analysis to enforce this in CI

The Semgrep rule that caught this issue can be run in your CI pipeline to prevent regressions:

semgrep --config "p/semgrep-rules" .github/dependabot.yml

Adding this check ensures that any future modification to dependabot.yml that removes the cooldown block will fail the build.

Relevant standards

  • CWE-1104: Use of Unmaintained Third-Party Components — directly applicable when unvetted packages are automatically adopted
  • OWASP A06:2021 – Vulnerable and Outdated Components — the supply chain risk of unreviewed dependency updates falls squarely in this category
  • SLSA (Supply Chain Levels for Software Artifacts) — recommends controls at every stage of the dependency pipeline, including a review window for new versions

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.


References

Frequently Asked Questions

What is a Dependabot missing cooldown vulnerability?

It means your Dependabot configuration has no waiting period before proposing updates to newly published package versions, so a malicious or unstable package could be automatically surfaced in a pull request within minutes of being published to a registry.

How do you prevent missing cooldown in Dependabot YAML?

Add a `cooldown` block with `default-days: 7` (or more) to every `package-ecosystem` entry in your `.github/dependabot.yml` file, so Dependabot waits that many days before opening a PR for a new package version.

What CWE is Dependabot missing cooldown?

It maps most closely to CWE-1104 (Use of Unmaintained Third-Party Components), since the absence of a cooldown increases the risk of inadvertently adopting unvetted or compromised third-party code.

Is pinning dependency versions enough to prevent supply chain attacks?

Pinning prevents unexpected upgrades, but it does not protect against a scenario where you intentionally upgrade to a newly published malicious version. A cooldown period adds a complementary layer of defense by delaying the proposal of brand-new releases.

Can static analysis detect a missing Dependabot cooldown?

Yes. Semgrep rules — such as `package_managers.dependabot.dependabot-missing-cooldown.dependabot-missing-cooldown` — can parse your `dependabot.yml` and flag any `updates` entry that lacks a `cooldown` block, making this easy to catch in CI.

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 Node.js dependencies and how to fix it

A high-severity Denial of Service vulnerability in the nanoid package (CVE-2026-67213) was discovered in the project's dependency tree, where crafted input could trigger an infinite loop during random ID generation. The fix upgrades nanoid from 3.3.17 to 3.3.18 and adds an npm override to ensure all transitive dependencies use the patched version.

high

How pnpm Missing Minimum Release Age happens in Node.js workspaces and how to fix it

A missing `minimumReleaseAge` setting in `pnpm-workspace.yaml` left this Node.js workspace vulnerable to immediately installing newly published — potentially malicious — package versions. The fix adds `minimumReleaseAge: 10080` (7 days in minutes) to enforce a quarantine window before any freshly published package can be installed. This single configuration change significantly reduces the risk of supply chain attacks targeting the package publishing pipeline.

high

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

A high-severity misconfiguration in `.github/dependabot.yml` left three `package-ecosystem` entries without a cooldown period, meaning Dependabot could immediately propose updates from newly published—potentially malicious—packages. The fix adds a `cooldown` block with `default-days: 7` to each entry, introducing a mandatory waiting period before any newly released package version is surfaced as an update candidate. For a Node.js library whose vulnerabilities ripple downstream to all consumers,

critical

How Unauthenticated Proxy Endpoints Enable DoS Amplification in FastAPI and how to fix it

Public proxy endpoints in `backend/api/proxy.py` had no rate limiting, allowing any attacker to flood the httpx connection pool with unauthenticated requests and amplify denial-of-service attacks against downstream tile and coordinate-conversion services. The fix introduces a per-IP sliding-window rate limiter using environment-configurable thresholds, closing the amplification vector without breaking legitimate usage.

high

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

A missing `cooldown` block in `.github/dependabot.yml` meant that Dependabot could immediately propose updates to newly published npm packages — including those that may be malicious, compromised, or unstable. By adding a `cooldown` with `default-days: 7`, the project now waits one week before surfacing new package versions, giving the security community time to detect and flag bad releases before they reach production.

high

How Shell Injection via os.system() happens in Python and how to fix it

A shell injection vulnerability in TensorFlow's DELF dataset download script allowed attackers who controlled the `data_dir` parameter to execute arbitrary shell commands by injecting metacharacters into `os.system()` calls. The fix replaces all four `os.system()` invocations with `subprocess.run()` using argument lists, eliminating shell interpretation entirely. This change closes a high-severity code execution path in production ML infrastructure.