Back to Blog
high SEVERITY8 min read

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

A high-severity misconfiguration in `.github/dependabot.yml` left this Node.js library without a cooldown period on dependency updates, meaning Dependabot could immediately propose upgrades to newly published — potentially malicious or unstable — package versions. The fix adds a `cooldown` block with `default-days: 7` to both the `npm` and `github-actions` ecosystems, introducing a mandatory waiting period before any newly released version is surfaced as an update candidate. Because this project

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

Answer Summary

A Dependabot Missing Cooldown vulnerability (CWE-1104) occurs when the `.github/dependabot.yml` file lacks a `cooldown` block, allowing Dependabot to immediately propose updates to packages published seconds ago — before the security community has had time to vet them for malicious code or instability. In this Node.js library, both the `npm` and `github-actions` package ecosystems were affected. The fix adds `cooldown: default-days: 7` to each ecosystem entry, enforcing a seven-day waiting period before any newly published version is eligible for an automated pull request.

Vulnerability at a Glance

cweCWE-1104 (Use of Unmaintained Third-Party Components)
fixAdded `cooldown: default-days: 7` to both the `npm` and `github-actions` ecosystems
riskAutomated dependency updates to newly published, unvetted, or malicious packages
languageYAML (GitHub Actions / Dependabot configuration)
root causeNo `cooldown` block defined in either `updates` entry of `.github/dependabot.yml`
vulnerabilityDependabot Missing Cooldown

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

Introduction

The .github/dependabot.yml file is the quiet workhorse of modern dependency hygiene — it tells GitHub's Dependabot when and how to propose version bumps across your project. But a missing configuration option in this file can silently expose your project — and every downstream consumer — to one of the most insidious supply-chain attack vectors: a malicious package published seconds ago being automatically proposed as an upgrade.

In this repository, a high-severity misconfiguration was detected at line 3 of .github/dependabot.yml: neither the npm ecosystem entry nor the github-actions ecosystem entry defined a cooldown period. Without this setting, Dependabot operates with zero delay — the moment a new version lands on the npm registry or the GitHub Marketplace, it becomes an eligible update candidate. For a Node.js library that downstream applications depend on, the blast radius of merging a compromised dependency is amplified well beyond the repository itself.


The Vulnerability Explained

What "no cooldown" actually means

When Dependabot scans for updates, it compares your pinned versions against the latest available in the configured package ecosystem. Without a cooldown block, the comparison is purely version-based: if a newer version exists, Dependabot opens a pull request. There is no built-in waiting period.

Here is the vulnerable configuration as it existed before the fix:

# .github/dependabot.yml (BEFORE — vulnerable)
version: 2
updates:
  - package-ecosystem: npm
    directory: "/"
    schedule:
      interval: cron
      cronjob: "0 5 10 */2 *"
    open-pull-requests-limit: 20
    groups:
      eslint:
        # ...

  - package-ecosystem: github-actions
    directory: "/"
    schedule:
      # Check for updates to GitHub Actions every weekday
      interval: daily

Neither updates entry contains a cooldown block. This means:

  1. A package published at 04:59 UTC could appear in a Dependabot PR at 05:00 UTC — one minute after publication.
  2. There is no opportunity for the npm security team, Snyk, Socket.dev, or community researchers to flag a malicious release before it lands in your review queue.
  3. Automated CI pipelines that auto-merge Dependabot PRs (a common pattern for patch updates) could merge a compromised package with zero human review.

The specific attack scenario

Consider the following realistic attack chain targeting this Node.js library:

  1. An attacker identifies a popular transitive dependency of this library — for example, a utility package with a small maintainer team.
  2. The attacker compromises the maintainer's npm token (via phishing, credential stuffing, or a leaked .npmrc) and publishes a malicious patch release, e.g., some-util@2.4.1, which contains a postinstall script that exfiltrates environment variables.
  3. Within hours, Dependabot opens a PR bumping some-util from 2.4.0 to 2.4.1.
  4. A developer, seeing only a patch version bump and a green CI pipeline (the malicious code runs at install time, not test time), merges the PR.
  5. Every downstream application that installs this library now executes the malicious postinstall script.

Without a cooldown, step 3 happens before the security community has had any realistic chance to detect and report the malicious release. The Socket.dev research team has documented dozens of real-world attacks that follow exactly this pattern, with the average time-to-detection for malicious npm packages measured in days, not hours.


The Fix

The fix is surgical and precise: add a cooldown block with default-days: 7 to each of the two package-ecosystem entries.

# .github/dependabot.yml (AFTER — fixed)
version: 2
updates:
  - package-ecosystem: npm
    directory: "/"
    schedule:
      interval: cron
      cronjob: "0 5 10 */2 *"
    cooldown:
      default-days: 7
    open-pull-requests-limit: 20
    groups:
      eslint:
        # ...

  - package-ecosystem: github-actions
    directory: "/"
    schedule:
      # Check for updates to GitHub Actions every weekday
      interval: daily
    cooldown:
      default-days: 7

Before vs. After

Aspect Before After
npm cooldown None — immediate proposals 7-day waiting period
github-actions cooldown None — immediate proposals 7-day waiting period
Malicious package window Minutes after publication At least 7 days
Community vetting time None Full week

Why 7 days?

Seven days is the GitHub-recommended default and aligns with real-world incident response timelines. Analysis of historical npm supply-chain incidents shows that the majority of malicious packages are identified and removed within 48–72 hours of publication — but not all. A 7-day window provides a comfortable buffer while still keeping dependencies reasonably current.

The cooldown block also supports semver-patch-days and semver-minor-days for more granular control if you want patch updates to move faster than major version bumps:

cooldown:
  default-days: 7
  semver-patch-days: 3   # Patch releases wait only 3 days
  semver-minor-days: 5   # Minor releases wait 5 days

Prevention & Best Practices

1. Always define a cooldown for every ecosystem

If your dependabot.yml manages multiple ecosystems (e.g., both npm and github-actions as in this case), every single updates entry needs its own cooldown block. A cooldown on one entry does not cascade to others.

2. Combine cooldown with dependency grouping

This repository already uses Dependabot's groups feature to batch related updates (e.g., all ESLint packages together). Combining grouping with a cooldown is a strong pattern: grouped updates reduce PR noise, and the cooldown ensures those grouped updates are only proposed after a vetting window.

3. Audit your auto-merge rules

If your repository has a GitHub Action that automatically merges Dependabot PRs (a common pattern using gh pr merge --auto), ensure your merge criteria include:
- Required status checks passing
- A minimum age on the PR (use branch protection rules or a custom check)
- Dependabot's own security alerts being clear

4. Use additional supply-chain tooling

A cooldown is one layer. Complement it with:
- Socket.dev GitHub App — scans PRs for malicious package behavior
- npm audit in CI — catches known vulnerabilities at install time
- Sigstore/provenance attestations — verify that packages were built from their claimed source

5. Static analysis for configuration files

The Semgrep rule package_managers.dependabot.dependabot-missing-cooldown.dependabot-missing-cooldown will catch this pattern in any repository. Adding Semgrep to your CI pipeline ensures this misconfiguration cannot silently reappear if the dependabot.yml is edited in the future.

Relevant standards

  • CWE-1104: Use of Unmaintained Third-Party Components — the broader category covering risks from unvetted dependency updates
  • OWASP A06:2021 – Vulnerable and Outdated Components — the OWASP Top 10 category that this misconfiguration directly impacts
  • SLSA (Supply-chain Levels for Software Artifacts) — a framework for hardening the full software supply chain, of which dependency update hygiene is a key component

Key Takeaways

  • Both ecosystem entries needed the fix independently. The npm and github-actions entries in this dependabot.yml each required their own cooldown block — there is no global default that covers all ecosystems at once.
  • A cron-scheduled Dependabot run without a cooldown is especially risky. This repository uses interval: cron with cronjob: "0 5 10 */2 *", meaning updates are checked on a fixed schedule. Without a cooldown, a package published the night before could be proposed at exactly 05:00 on the next scheduled run.
  • Node.js libraries amplify supply-chain risk. Because this is a library (not an application), any compromised dependency it adopts is transitively inherited by all downstream consumers — multiplying the potential impact.
  • The open-pull-requests-limit: 20 setting makes cooldown more important, not less. A high PR limit means Dependabot can open many update PRs in a single run, increasing the surface area for a malicious package to slip through during a busy review period.
  • Seven days is a minimum, not a maximum. For production-critical libraries, consider default-days: 14 or requiring manual approval for major version bumps regardless of cooldown.

How Orbis AppSec Detected This

  • Source: The .github/dependabot.yml configuration file at line 3, where the updates array is defined without any cooldown constraint on either ecosystem entry.
  • Sink: The Dependabot update proposal mechanism itself — specifically, the absence of a cooldown block means any newly published package version immediately becomes eligible for an automated PR, with no waiting period before it reaches developer review queues.
  • Missing control: No cooldown: default-days value was set for either the npm or the github-actions package ecosystem entries, removing the only time-based gate that prevents Dependabot from proposing unvetted package versions.
  • CWE: CWE-1104 — Use of Unmaintained Third-Party Components (by extension, use of unvetted newly published components).
  • Fix: Added cooldown: default-days: 7 to both the npm entry (after the cronjob schedule line) and the github-actions entry (after the interval: daily schedule line) in .github/dependabot.yml.

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 in dependabot.yml is easy to overlook — it is an absence of configuration rather than a piece of broken code, which makes it invisible to most code reviewers. Yet the consequences are concrete: without a waiting period, automated dependency updates become a reliable delivery mechanism for supply-chain attacks, particularly against high-value targets like widely consumed Node.js libraries.

The fix in this case was two four-line additions to .github/dependabot.yml — a trivially small change that closes a meaningful attack window. The broader lesson is that security configuration files deserve the same scrutiny as application code, and that static analysis tools like Semgrep can catch these misconfigurations before they become incidents.

Review your own dependabot.yml files today. If you see an updates entry without a cooldown block, add one.


References

Frequently Asked Questions

What is a Dependabot Missing Cooldown vulnerability?

It is a misconfiguration where Dependabot is not told to wait before proposing updates to newly published package versions, meaning potentially malicious or broken releases can be automatically surfaced as PRs within minutes of publication.

How do you prevent a missing cooldown in Dependabot YAML?

Add a `cooldown` block with `default-days: 7` (or higher) inside every `package-ecosystem` entry under the `updates` key 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 likelihood of adopting unreviewed or compromised component versions.

Is pinning dependency versions enough to prevent supply-chain attacks via Dependabot?

No. Pinning prevents unexpected upgrades in production, but Dependabot PRs can still introduce malicious versions into review and CI pipelines if no cooldown is set. A cooldown adds a time buffer during which the community can identify and report bad releases.

Can static analysis detect a missing Dependabot cooldown?

Yes. Semgrep rule `package_managers.dependabot.dependabot-missing-cooldown.dependabot-missing-cooldown` flags any `updates` entry in `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 #451

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.