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 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, meaning Dependabot would immediately propose updates to newly published packages — including potentially malicious or unstable ones. The fix adds a `cooldown` block with `default-days: 7` to both the `npm` and `github-actions` package ecosystem entries, introducing a mandatory 7-day waiting period before any new package version is surfaced as an update candidate.

critical

How CSRF Protection Failures Happen in FastAPI and How to Fix Them

A critical CORS misconfiguration in `backend/main.py` allowed cookies to be sent alongside wildcard-origin requests, violating the CORS specification and opening the door to cross-site request forgery attacks. The fix conditionally disables `allow_credentials` when the allowed origins list contains a wildcard, bringing the configuration into compliance with browser security rules. This change closes a subtle but dangerous gap that could have let attackers on sibling subdomains forge authenticate

critical

How Missing Rate Limiting Happens in Node.js SSE Handlers and How to Fix It

A critical missing rate-limiting control in `src/sse/handlers/chat.js` allowed any caller to flood the SSE chat endpoint with unlimited requests, risking server resource exhaustion, denial of service, and runaway AI provider API costs. The fix introduces a per-IP sliding-window rate limiter that caps requests at 60 per minute and returns HTTP 429 on violations. Because the endpoint was publicly reachable and only validated API keys — not request frequency — exploitation required nothing more tha

medium

How Denial of Service via Catastrophic Backtracking happens in Node.js and how to fix it

CVE-2026-4867 is a Denial of Service vulnerability in path-to-regexp 0.1.12 where malformed URL parameters can trigger catastrophic backtracking in the library's regular expression engine, allowing an attacker to hang or crash a Node.js application with a single crafted request. The fix upgrades path-to-regexp to version 0.1.13, which patches the vulnerable regex patterns. This change was applied via a package-level override to ensure the patched version is used throughout the entire dependency

high

How Denial of Service via Exponential-Time Complexity happens in Node.js and how to fix it

CVE-2026-13149 is a high-severity Denial of Service vulnerability in the `brace-expansion` npm package, where crafted input strings trigger exponential-time processing that can freeze or crash a Node.js application. The fix upgrades `brace-expansion` from `2.0.2` to `2.1.4` and `minimatch` from `5.1.6` to `5.1.9`, along with npm `overrides` to ensure the patched versions are used throughout the entire dependency tree.

critical

How Unrestricted File Upload happens in Node.js/Express and how to fix it

A critical unrestricted file upload vulnerability was discovered in `mainsystem/routes/admin/profile.js`, where the avatar upload endpoint accepted any file type without validation. An authenticated attacker could upload a malicious server-side script to a web-accessible directory and execute arbitrary code on the server. The fix adds MIME type filtering, an allowlist of safe image formats, and a 2 MB file size limit to the multer middleware.