Back to Blog
high SEVERITY8 min read

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 and GitHub Actions packages — including potentially malicious or unstable releases. By adding a `cooldown: default-days: 3` block to each `package-ecosystem` entry, the project now waits three days before surfacing new package versions, giving the community time to detect supply-chain threats before they reach the codebase.

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

Answer Summary

A Dependabot Missing Cooldown vulnerability (CWE-1104) in `.github/dependabot.yml` allowed Dependabot to immediately propose updates to newly published packages without any waiting period, exposing the project to supply-chain attacks via malicious or unstable releases. The fix adds a `cooldown: default-days: 3` block to both the `npm` and `github-actions` package-ecosystem entries, introducing a three-day buffer before Dependabot surfaces new versions. This is a configuration-level hardening measure recommended by GitHub's own security documentation for any project that uses automated dependency updates.

Vulnerability at a Glance

cweCWE-1104 (Use of Unmaintained Third-Party Components)
fixAdded `cooldown: default-days: 3` to both the `npm` and `github-actions` entries in `.github/dependabot.yml`
riskAutomatic dependency updates can pull in malicious or unstable packages within minutes of publication
languageYAML (GitHub Actions / Dependabot configuration)
root causeNo `cooldown` block defined in either `package-ecosystem` entry 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 one of the most quietly powerful security controls in a modern repository. It decides when and how your project adopts new versions of every dependency — from production npm packages to the GitHub Actions that build and deploy your code. In this Node.js library, Dependabot was configured to check for updates on a daily schedule for both the npm and github-actions ecosystems. That sounds responsible. The problem is that "daily" with no cooldown means Dependabot could open a pull request for a package version published just hours ago — before anyone in the open-source community has had a chance to inspect it for malice or instability.

The Semgrep rule package_managers.dependabot.dependabot-missing-cooldown.dependabot-missing-cooldown flagged line 3 of .github/dependabot.yml because neither package-ecosystem entry contained a cooldown block. This post explains what that means, why it matters for a Node.js library whose vulnerabilities flow downstream to every consumer, and exactly how the fix works.


The Vulnerability Explained

What the vulnerable configuration looked like

Before the fix, both ecosystem entries in .github/dependabot.yml looked structurally like this:

# BEFORE — no cooldown block
updates:
  - package-ecosystem: npm
    directory: "/"
    schedule:
      interval: daily
    groups:
      eslint-dependencies:
        patterns:
          - "eslint*"
  - package-ecosystem: github-actions
    directory: "/"
    schedule:
      interval: "daily"

There is nothing in either entry that tells Dependabot to wait before proposing a newly published version. The moment a package maintainer — or an attacker who has compromised a maintainer's account — publishes a new version, Dependabot's next daily run will open a pull request for it.

Why this is dangerous for a Node.js library

Supply-chain attacks against npm have become a well-documented threat vector. Attackers use several techniques:

  • Account takeover: Compromise a maintainer's npm credentials and publish a malicious patch release.
  • Dependency confusion: Register a package on npm with the same name as a private internal package.
  • Typosquatting: Publish a package whose name is one character away from a popular one and wait for automated tooling to pick it up.

In all three scenarios, the attack window is the gap between publication and community detection. Security researchers, automated scanners, and vigilant users typically need at least 24–72 hours to notice and report a malicious release. Without a cooldown, Dependabot operates entirely inside that window — it will surface the malicious version before the community has had a chance to flag it.

Because this is a Node.js library, the blast radius extends beyond this single repository. Every downstream project that depends on this library is also at risk if a compromised dependency is merged and shipped in a new release.

The specific attack scenario

  1. An attacker compromises the npm account of a maintainer of a package listed in the project's eslint-dependencies group (e.g., eslint-plugin-*).
  2. The attacker publishes eslint-plugin-example@3.2.1 containing a postinstall script that exfiltrates environment variables.
  3. Within 24 hours, Dependabot opens a PR: "Bump eslint-plugin-example from 3.2.0 to 3.2.1".
  4. A developer, seeing a routine eslint plugin bump, approves and merges without deep inspection.
  5. The malicious postinstall script runs on every developer machine and CI runner that installs dependencies.

A 3-day cooldown means this PR would not even appear until day 3 — by which time npm's security team or community researchers would very likely have yanked the package.


The Fix

What changed

Two cooldown blocks were added — one to each package-ecosystem entry:

# AFTER — cooldown added to both ecosystems
updates:
  - package-ecosystem: npm
    directory: "/"
    schedule:
      interval: daily
    cooldown:           # <-- NEW
      default-days: 3  # <-- NEW
    groups:
      eslint-dependencies:
        patterns:
          - "eslint*"

  - package-ecosystem: github-actions
    directory: "/"
    schedule:
      interval: "daily"
    cooldown:           # <-- NEW
      default-days: 3  # <-- NEW

Before vs. after

Aspect Before After
npm updates proposed after publish Immediately (next daily run) After 3 days
github-actions updates proposed after publish Immediately (next daily run) After 3 days
Exposure window to zero-day supply-chain attack Up to 24 hours Reduced to near-zero for attacks detected within 3 days
Dependabot PR noise from unstable releases High (yanked packages still generate PRs) Significantly reduced

Why 3 days?

GitHub's own documentation recommends default-days: 7 as a conservative baseline. This project chose default-days: 3 — a pragmatic middle ground that still covers the majority of supply-chain attack detection timelines while keeping the project reasonably up to date. Teams with stricter security requirements or slower review cadences should consider the full 7-day window.

The cooldown block also supports semver-patch-days and semver-minor-days keys, allowing finer-grained control (e.g., letting patch releases through faster while holding minor and major updates longer). For this project, a single default-days: 3 rule was sufficient.


Prevention & Best Practices

Always include a cooldown block in new Dependabot configurations

When creating a new dependabot.yml, treat cooldown as a required field rather than an optional one. A minimal, secure template looks like:

version: 2
updates:
  - package-ecosystem: npm
    directory: "/"
    schedule:
      interval: weekly
    cooldown:
      default-days: 7

Use Semgrep to enforce the policy in CI

The rule that caught this issue — package_managers.dependabot.dependabot-missing-cooldown.dependabot-missing-cooldown — can be run in your CI pipeline to prevent the configuration from regressing:

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

Adding this as a required check means a future edit that accidentally removes the cooldown block will be caught before it merges.

Layer your supply-chain defences

A cooldown period is one layer, not a complete defence. Combine it with:

  • Lockfile verification: Commit package-lock.json and verify it in CI with npm ci rather than npm install.
  • Provenance attestations: Use npm's --audit flag and check for packages with SLSA provenance.
  • Dependency review: Enable GitHub's Dependency Review action to block PRs that introduce known vulnerabilities.
  • Pinned Actions versions: For github-actions, pin to a full commit SHA rather than a mutable tag to prevent tag-moving attacks.

Relevant standards

  • CWE-1104: Use of Unmaintained Third-Party Components — the closest CWE mapping for supply-chain configuration weaknesses.
  • OWASP A06:2021 – Vulnerable and Outdated Components: Covers risks from unvetted third-party dependencies.
  • SLSA Supply Chain Levels: A framework for hardening the entire software supply chain, of which dependency update hygiene is a foundational step.

Key Takeaways

  • Both ecosystem entries needed fixing independently. The npm and github-actions entries in .github/dependabot.yml are separate configurations; a cooldown block must be added to each one explicitly — there is no global default.
  • A daily update schedule without a cooldown is more dangerous than a weekly schedule with one. Frequency of checking is irrelevant if there is no buffer between publication and proposal.
  • The eslint-dependencies group makes this especially risky. Grouping all eslint* packages means a single compromised eslint plugin could be bundled into a grouped PR that looks routine and gets less scrutiny.
  • Three days is a minimum, not a ceiling. For projects with slower review cycles or higher security requirements, default-days: 7 (GitHub's recommendation) is the safer choice.
  • This is a Node.js library — downstream consumers inherit the risk. Configuration weaknesses in a library's own toolchain can propagate malicious code to every project that depends on it.

How Orbis AppSec Detected This

  • Source: The .github/dependabot.yml configuration file, specifically the two package-ecosystem entries beginning at line 3, which control how and when Dependabot proposes dependency updates.
  • Sink: The absence of a cooldown block in either entry, meaning Dependabot's update proposals are not gated by any publication-age check before being surfaced to developers.
  • Missing control: No cooldown: default-days value was set for either the npm or github-actions ecosystem, leaving zero buffer between package publication and PR creation.
  • CWE: CWE-1104 — Use of Unmaintained Third-Party Components (extended here to cover unvetted newly published components).
  • Fix: Added cooldown: default-days: 3 to both the npm and github-actions entries in .github/dependabot.yml, introducing a three-day waiting period before Dependabot proposes updates to newly published versions.

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 block in Dependabot configuration is easy to overlook — it doesn't cause a build failure, doesn't appear in runtime logs, and doesn't trigger any obvious warning. But for a Node.js library with a daily update schedule, it represents a real and specific supply-chain risk: the window between a malicious package publication and a Dependabot-generated PR can be measured in hours. Adding cooldown: default-days: 3 to both the npm and github-actions entries closes that window for the vast majority of supply-chain attacks, which are typically detected and reported within 72 hours of publication. Treat the cooldown block as a required field in every Dependabot configuration you write, and back it up with lockfile verification, dependency review, and pinned Action versions for a defence-in-depth posture.


References

Frequently Asked Questions

What is a Dependabot Missing Cooldown vulnerability?

It is a configuration gap where Dependabot is set up to propose dependency updates without any waiting period after a new package version is published, meaning a malicious or broken release can reach your pull-request queue within minutes.

How do you prevent a missing cooldown in Dependabot YAML?

Add a `cooldown` block with a `default-days` value (GitHub recommends 7; this project uses 3) to every `package-ecosystem` entry in `.github/dependabot.yml`.

What CWE is Dependabot Missing Cooldown?

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

Is enabling Dependabot alone enough to prevent supply-chain attacks?

No. Dependabot automates update discovery, but without a cooldown period it can surface malicious packages before the community has had time to detect and report them. A cooldown, combined with code review and lockfile verification, provides layered defence.

Can static analysis detect a missing Dependabot cooldown?

Yes. The Semgrep rule `package_managers.dependabot.dependabot-missing-cooldown.dependabot-missing-cooldown` matches any `dependabot.yml` that lacks a `cooldown` block, which is exactly how this issue was found.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #623

Related Articles

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 dependabot-missing-cooldown happens in GitHub Actions/Node.js and how to fix it

The repository's `.github/dependabot.yml` had no cooldown period configured, meaning Dependabot could immediately propose updates to newly published package versions with zero time for the community to flag malware or instability. The fix adds a `cooldown` block with `default-days: 7` to both the `npm` and `github-actions` ecosystems, forcing a 7-day waiting period before new releases are surfaced as update PRs.

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.