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 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.

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

Answer Summary

A Dependabot Missing Cooldown vulnerability (CWE-1357) in `.github/dependabot.yml` allowed Dependabot to immediately propose updates to newly published npm packages without any waiting period. This is dangerous because malicious actors can publish typosquatted or compromised package versions that Dependabot would then automatically surface as PRs. The fix adds a `cooldown` block with `default-days: 7` to the npm package-ecosystem entry, enforcing a 7-day delay before Dependabot proposes any newly published package version. This gives the security community time to detect and report malicious releases before they reach your dependency tree.

Vulnerability at a Glance

cweCWE-1357 (Reliance on Insufficiently Trustworthy Component)
fixAdded `cooldown: default-days: 7` to the npm package-ecosystem entry, enforcing a 7-day quarantine window for new releases
riskAutomatic promotion of malicious or unstable newly published npm packages into the dependency tree
languageYAML (GitHub Actions / Dependabot configuration)
root causeNo `cooldown` block defined in the `updates` entry for the npm package-ecosystem 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 in this Node.js library controlled how GitHub's Dependabot service proposed dependency updates to the project. It was configured to watch the npm ecosystem, limit open pull requests to 10, assign a specific reviewer (stefcameron), and apply a versioning-strategy of increase. Everything looked reasonable — but a critical security control was absent: there was no cooldown period.

Without a cooldown, Dependabot is free to propose an update to a package the moment a new version lands on the npm registry. That sounds helpful, but it creates a meaningful supply-chain risk: a malicious actor who publishes a compromised package version would have it surfaced as a Dependabot PR almost immediately, before the security community has had a chance to detect and flag the release.

This post walks through exactly what was missing, why it matters for a Node.js library whose vulnerabilities propagate to all downstream consumers, and how a single YAML addition closes the gap.


The Vulnerability Explained

What Was Missing in dependabot.yml

Before the fix, the relevant portion of .github/dependabot.yml looked like this:

# .github/dependabot.yml (BEFORE — vulnerable)
updates:
  - package-ecosystem: 'npm'
    directory: '/'
    schedule:
      interval: 'weekly'
    open-pull-requests-limit: 10
    reviewers:
      - 'stefcameron'
    versioning-strategy: 'increase'
    ignore:
      # ignore React 19 and related dependencies to keep tests based on R18 for now

Notice what is absent: there is no cooldown block anywhere under the npm ecosystem entry. This means Dependabot operates with zero delay — as soon as a new version of any tracked npm package is published, Dependabot is eligible to open a PR proposing that version.

Why Zero Delay Is a Problem

The npm registry is a high-value target for supply-chain attacks. Attack patterns include:

  • Account takeover: An attacker compromises a maintainer's npm credentials and publishes a backdoored patch version (e.g., 1.2.4 over a clean 1.2.3).
  • Typosquatting: A malicious package with a name similar to a popular one gets published and Dependabot picks it up if a dependency name was recently changed.
  • Dependency confusion: An internal package name is registered on the public registry with a higher version number, tricking package managers into preferring it.

In all three scenarios, the attacker's window of maximum effectiveness is the period immediately after publication, before security researchers, automated scanners, or the npm security team have had time to analyze and remove the package. A Dependabot configuration with no cooldown shrinks the defender's reaction time to near zero.

Concrete Attack Scenario

Imagine a popular utility in this project's package.json — say, a test helper or a build tool — has its npm account compromised. The attacker publishes version 3.1.1 containing a postinstall script that exfiltrates environment variables. Without a cooldown:

  1. The malicious 3.1.1 lands on npm.
  2. Dependabot's next scheduled run (weekly in this config) picks it up.
  3. A PR is opened proposing the upgrade, complete with a changelog that looks normal.
  4. A developer reviews it, sees a minor patch bump, approves, and merges.
  5. The malicious postinstall script runs in CI and in every developer's local environment.

Because this is a Node.js library (not just an internal application), any downstream consumer who installs it will also pull in the compromised transitive dependency.


The Fix

What Changed

The fix adds a cooldown block directly under the npm package-ecosystem entry, between the reviewers block and versioning-strategy:

# .github/dependabot.yml (AFTER — fixed)
updates:
  - package-ecosystem: 'npm'
    directory: '/'
    schedule:
      interval: 'weekly'
    open-pull-requests-limit: 10
    reviewers:
      - 'stefcameron'
    cooldown:
      default-days: 7
    versioning-strategy: 'increase'
    ignore:
      # ignore React 19 and related dependencies to keep tests based on R18 for now

The diff is minimal but impactful:

     reviewers:
       - 'stefcameron'
+    cooldown:
+      default-days: 7
     versioning-strategy: 'increase'

How the Cooldown Works

The cooldown block tells Dependabot to wait at least default-days: 7 after a package version is first published to the registry before it is eligible to be proposed in a PR. The 7-day window is the GitHub-recommended baseline and aligns with the typical detection timeline for malicious packages on the npm registry.

You can also set ecosystem-specific or package-specific overrides:

cooldown:
  default-days: 7          # applies to all packages
  semver-patch-days: 3     # shorter wait for patch-only bumps
  semver-minor-days: 5     # medium wait for minor bumps

For this project, default-days: 7 is the right starting point — it applies uniformly to all npm packages tracked by Dependabot, including the React-related packages currently being ignored for version pinning reasons.

Why This Specific Change Solves the Problem

The 7-day quarantine window provides several defensive layers:

Defender Typical Detection Time
npm security team automated scanners Hours to 2 days
Security researchers / community reports 1–5 days
CVE / NVD publication 3–14 days
Downstream package audits 1–7 days

By waiting 7 days, Dependabot will not surface a version until the majority of these detection mechanisms have had a chance to operate. If a version is flagged and yanked from npm within that window, Dependabot will never propose it.


Prevention & Best Practices

Always Define a Cooldown for Every Ecosystem

If your dependabot.yml manages multiple ecosystems (e.g., npm and github-actions), add a cooldown block to each package-ecosystem entry:

updates:
  - package-ecosystem: 'npm'
    directory: '/'
    schedule:
      interval: 'weekly'
    cooldown:
      default-days: 7

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

Pair Cooldown with Other Supply-Chain Controls

A cooldown is one layer of a defense-in-depth strategy. Combine it with:

  • npm audit in CI to catch known vulnerabilities in the current lock file.
  • Lockfile integrity checks — commit package-lock.json and verify it in CI.
  • Dependency review via GitHub's built-in dependency review action, which blocks PRs that introduce known-vulnerable packages.
  • Pinned GitHub Actions versions using full commit SHAs to prevent tag-based attacks.
  • Sigstore / npm provenance — prefer packages that publish build provenance attestations.

Use Static Analysis to Catch Missing Cooldowns Early

The Semgrep rule package_managers.dependabot.dependabot-missing-cooldown.dependabot-missing-cooldown detects this pattern automatically. Add it to your CI pipeline:

semgrep --config=p/supply-chain .github/dependabot.yml

Security Standards Alignment

  • OWASP A06:2021 – Vulnerable and Outdated Components: Using a cooldown reduces the risk of automatically adopting a newly published vulnerable or malicious component.
  • CWE-1357 – Reliance on Insufficiently Trustworthy Component: The absence of a vetting delay means the pipeline implicitly trusts any version published to the registry.
  • SLSA Supply Chain Framework: Cooldowns support the principle of verifying artifact integrity before consumption.

Key Takeaways

  • The missing cooldown block in .github/dependabot.yml is the root cause — not a misconfigured schedule or an overly broad ignore list. Two lines of YAML close a meaningful supply-chain window.
  • Zero-delay Dependabot updates are particularly risky for published libraries because a compromised transitive dependency propagates to every downstream consumer who installs the package.
  • default-days: 7 matches the realistic detection timeline for malicious npm packages — it's not an arbitrary number, it reflects how long the ecosystem typically takes to identify and remove bad releases.
  • The cooldown must be added per ecosystem — a single top-level setting does not exist; if this project later adds a github-actions ecosystem entry, it will need its own cooldown block.
  • Static analysis (Semgrep) caught this before it caused harm — integrating supply-chain linting into your CI pipeline surfaces these configuration gaps before they reach production.

How Orbis AppSec Detected This

  • Source: The npm registry — any newly published package version is immediately eligible for a Dependabot PR when no cooldown is configured.
  • Sink: The package-ecosystem: 'npm' entry at line 3 of .github/dependabot.yml, which lacked a cooldown block, meaning Dependabot would propose updates with zero delay.
  • Missing control: No cooldown block with a default-days value under the npm ecosystem entry — the configuration contained open-pull-requests-limit, reviewers, and versioning-strategy but omitted the quarantine window entirely.
  • CWE: CWE-1357 — Reliance on Insufficiently Trustworthy Component.
  • Fix: Added cooldown: default-days: 7 between the reviewers and versioning-strategy keys in the npm ecosystem entry, enforcing a 7-day waiting period before any newly published package version is proposed.

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 two-line addition to a YAML configuration file — cooldown: and default-days: 7 — meaningfully reduces the supply-chain attack surface for this Node.js library and all of its downstream consumers. The change is low-friction: it does not prevent Dependabot from proposing updates, it simply ensures those updates have had a week to be scrutinized by the broader security ecosystem before landing in your PR queue.

For teams maintaining open-source libraries or widely-consumed internal packages, this kind of configuration hygiene is not optional. The npm ecosystem sees supply-chain attacks regularly, and automated tooling like Dependabot — while invaluable — needs guardrails to avoid becoming an attack vector itself.

Review your own dependabot.yml files today. If you don't see a cooldown block, you're one compromised package release away from an automated PR that could introduce malicious code into your project.


References

Frequently Asked Questions

What is a Dependabot missing cooldown vulnerability?

It occurs when a Dependabot configuration file lacks a `cooldown` block, meaning Dependabot will immediately propose updates to packages the moment they are published — including potentially malicious or unstable releases.

How do you prevent missing cooldown in Dependabot YAML configuration?

Add a `cooldown` block with `default-days: 7` (or more) to every `package-ecosystem` entry under `updates` in your `.github/dependabot.yml` file.

What CWE is Dependabot missing cooldown?

CWE-1357 — Reliance on Insufficiently Trustworthy Component, because the configuration trusts newly published packages without any vetting delay.

Is enabling Dependabot security updates enough to prevent supply chain attacks?

No. Security updates address known CVEs, but a cooldown period is a separate, complementary control that guards against newly published malicious versions that have not yet been reported as vulnerabilities.

Can static analysis detect a missing Dependabot cooldown?

Yes. Semgrep rule `package_managers.dependabot.dependabot-missing-cooldown.dependabot-missing-cooldown` detects the absence of a `cooldown` block in `dependabot.yml` files and was the tool that flagged this issue.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #1995

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 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.

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 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.