Back to Blog
high SEVERITY9 min read

How missing Dependabot cooldown happens in Node.js GitHub Actions and how to fix it

A missing cooldown period in `.github/dependabot.yml` meant that newly published npm and GitHub Actions packages could be automatically proposed for adoption within minutes of release — before the security community has time to vet them. This high-severity finding was fixed by adding a `cooldown` block with `default-days: 7` to every `package-ecosystem` entry, giving the ecosystem time to flag malicious or unstable releases before they reach the codebase. Because this is a Node.js library, the r

O
By Orbis AppSec
Published July 25, 2026Reviewed July 25, 2026

Answer Summary

A missing Dependabot cooldown (related to CWE-1104: Use of Unmaintained Third-Party Components and software supply-chain risk) in `.github/dependabot.yml` allowed Dependabot to immediately propose updates to freshly published npm and GitHub Actions packages — including potentially malicious ones — with no waiting period. The fix adds a `cooldown` block (`default-days: 7`) to both the `npm` and `github-actions` package-ecosystem entries, ensuring no update PR is opened until a package version has been publicly available for at least seven days. This gives the security community time to identify and report compromised or typosquatted releases before they are automatically merged into the project and shipped to downstream consumers.

Vulnerability at a Glance

cweCWE-1104 (Use of Unmaintained Third-Party Components / inadequate supply-chain controls)
fixAdded `cooldown: default-days: 7` to every `package-ecosystem` entry so updates are withheld for seven days after a package version is published
riskAutomatic adoption of malicious or unstable newly published packages before the security community can vet them
languageYAML (GitHub Actions / Node.js ecosystem)
root causeNo `cooldown` block in either `package-ecosystem` entry of `.github/dependabot.yml`, allowing zero-delay update proposals
vulnerabilityMissing Dependabot cooldown period

How missing Dependabot cooldown happens in Node.js 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 fast your project adopts new versions of every dependency it relies on. In this Node.js library, that file contained a high-severity misconfiguration: neither the npm ecosystem entry nor the github-actions ecosystem entry defined a cooldown period. As a result, Dependabot was free to open update pull requests the instant a new package version appeared on the registry — a window that sophisticated supply-chain attackers deliberately exploit.

Because this project is a Node.js library, the blast radius extends beyond the repository itself. Every downstream consumer that installs this package inherits whatever dependencies it ships with. A compromised transitive dependency merged today can silently reach thousands of production environments within hours.


The Vulnerability Explained

What a cooldown period does (and what happens without one)

When Dependabot has no cooldown configuration, it evaluates new package versions as soon as its scheduler fires — in this case, daily for both ecosystems. That means a package published at midnight could have an open pull request in this repository by the following morning, long before:

  • The npm security team or community has reviewed the release.
  • Automated malware scanners have processed the new tarball.
  • The original maintainer has noticed their account was compromised.

The vulnerable configuration (before the fix) looked like this for the npm ecosystem:

# BEFORE — no cooldown at all on the first npm entry
- package-ecosystem: npm
  directory: /
  schedule:
    interval: daily
  commit-message:
    prefix: "fix(deps):"
    prefix-development: "chore(deps):"
  labels:
    - npm dependencies

And the github-actions entry was identical in its omission:

# BEFORE — no cooldown on github-actions
- package-ecosystem: github-actions
  directory: /
  schedule:
    interval: daily
  commit-message:
    prefix: "chore(action):"
  labels:
    - dependencies

A second pair of entries did have a cooldown block, but it was set to only 2 days — far too short to provide meaningful protection:

cooldown:
  default-days: 2   # ← 2 days is not enough

The net result: some ecosystem entries had zero protection, and others had a cooldown so short it offered only marginal defence.

How an attacker exploits this

Supply-chain attacks against npm packages follow a well-documented playbook:

  1. Account takeover — An attacker compromises a maintainer's npm credentials (often via credential stuffing or phishing).
  2. Malicious publish — They publish a new patch or minor version of a popular package containing a backdoor, credential harvester, or cryptominer.
  3. Race the bots — Automated dependency update tools like Dependabot pick up the new version within hours and open pull requests across thousands of repositories.
  4. Auto-merge or fast merge — Projects with auto-merge enabled, or maintainers who trust Dependabot implicitly, merge the PR before any advisory is published.

With interval: daily and no cooldown, this repository sat squarely in that race window. The 2-day cooldown on the duplicate entries barely helped: many high-profile supply-chain incidents (e.g., the event-stream compromise, the ua-parser-js hijack) were identified within 24–72 hours — but only after many projects had already merged the malicious version.

Real-world impact for this project

Because this is a Node.js library (not just an application), a compromised dependency merged here would be:

  • Bundled into the library's own published npm package.
  • Silently distributed to every consumer on their next npm install or npm update.
  • Potentially executed in CI pipelines, servers, and developer machines with no further action required by the consumer.

The github-actions ecosystem carries its own risk: a malicious action version could exfiltrate GITHUB_TOKEN, repository secrets, or source code from every workflow run.


The Fix

The fix consolidates and corrects the dependabot.yml configuration in two ways:

  1. Removes duplicate entries — The file previously had four package-ecosystem blocks (two npm entries and two github-actions entries). The fix reduces this to one entry per ecosystem, eliminating the confusion that allowed some entries to exist without a cooldown.
  2. Sets default-days: 7 on every entry — Seven days is the threshold recommended by GitHub's own documentation and gives the security community a meaningful window to identify and disclose compromised releases.

Before and after

npm ecosystem — before:

- package-ecosystem: npm
  directory: /
  schedule:
    interval: daily
  # ← no cooldown whatsoever
  commit-message:
    prefix: "fix(deps):"
    prefix-development: "chore(deps):"
  labels:
    - npm dependencies

npm ecosystem — after:

- package-ecosystem: npm
  directory: /
  schedule:
    interval: daily
  cooldown:
    default-days: 7          # ← wait 7 days after publish
  commit-message:
    prefix: "fix(deps):"
    prefix-development: "chore(deps):"
  labels:
    - npm dependencies

github-actions ecosystem — before:

- package-ecosystem: github-actions
  directory: /
  schedule:
    interval: daily
  # ← no cooldown
  commit-message:
    prefix: "chore(action):"
  labels:
    - build dependencies

github-actions ecosystem — after:

- package-ecosystem: github-actions
  directory: /
  schedule:
    interval: daily
  cooldown:
    default-days: 7          # ← wait 7 days after publish
  commit-message:
    prefix: "chore(action):"
  labels:
    - dependencies

The cooldown block also supports more granular control. For example, if you want to apply a longer hold to production dependencies but a shorter one to development tooling:

cooldown:
  default-days: 7
  semver-patch-days: 3       # patch versions wait only 3 days
  semver-minor-days: 5       # minor versions wait 5 days

This level of tuning is optional but worth considering for teams that need faster patch cycles while still protecting against major/minor version supply-chain attacks.

Why 7 days specifically?

GitHub's own documentation recommends 7 days as the default cooldown. Analysis of historical supply-chain incidents shows that the majority of malicious package versions are identified and removed from registries within 3–7 days of publication. A 7-day window therefore catches most incidents before they reach your package-lock.json.


Prevention & Best Practices

1. Always define a cooldown in dependabot.yml

Every package-ecosystem entry should have a cooldown block. Treat its absence as a misconfiguration, not a default that is safe to skip.

# Minimum recommended configuration
cooldown:
  default-days: 7

2. Audit for duplicate ecosystem entries

The original file had four entries where two were needed. Duplicate entries create confusion and make it easy for one copy to drift out of sync with security settings. Lint your dependabot.yml as part of CI.

3. Do not rely on auto-merge without a cooldown

Auto-merge for Dependabot PRs is a productivity win, but it is dangerous without a cooldown. If you use auto-merge (via gh CLI, GitHub's built-in feature, or a third-party action), pair it with default-days: 7 at a minimum.

4. Enable npm provenance and Sigstore verification

For npm packages, provenance attestations (available since npm 9.5) allow you to verify that a package was built from a specific commit in a specific repository. Combined with a cooldown, this significantly raises the bar for supply-chain attacks.

5. Use Semgrep in CI to catch future regressions

The Semgrep rule that detected this issue — package_managers.dependabot.dependabot-missing-cooldown.dependabot-missing-cooldown — can be run in CI to prevent the cooldown from being accidentally removed in future PRs:

# .github/workflows/semgrep.yml (excerpt)
- name: Run Semgrep
  run: semgrep --config "p/supply-chain" .github/dependabot.yml

6. Monitor the npm advisory database

Subscribe to GitHub Advisory Database notifications for your key dependencies. Even with a cooldown, staying informed lets you act immediately when a critical advisory drops.

OWASP and CWE context

This vulnerability maps to:

  • OWASP A06:2021 — Vulnerable and Outdated Components: Specifically the risk of automatically adopting unvetted component versions.
  • CWE-1104: Use of Unmaintained Third-Party Components — the broader category covering inadequate controls over third-party dependency ingestion.

Key Takeaways

  • A cooldown block is not optional — every package-ecosystem entry in .github/dependabot.yml must have one. An entry without cooldown is a zero-delay pipeline from the npm registry to your codebase.
  • default-days: 2 is not enough — the original partial fix used a 2-day cooldown, which is shorter than the average time it takes for malicious packages to be detected and removed. Seven days is the community-recommended minimum.
  • Duplicate ecosystem entries are a maintenance hazard — having four entries (two npm, two github-actions) meant security settings could diverge silently. Consolidate to one entry per ecosystem.
  • Daily schedule + no cooldown = maximum exposure — the interval: daily schedule is aggressive. Without a cooldown it means Dependabot checks for new versions every day and proposes them immediately, maximising the chance of racing a supply-chain attack.
  • Library projects have amplified blast radius — because this is a Node.js library, a compromised dependency doesn't just affect this repository; it propagates to every consumer on their next install.

How Orbis AppSec Detected This

  • Source: The dependabot.yml configuration file at .github/dependabot.yml, line 3 — specifically the package-ecosystem: npm and package-ecosystem: github-actions entries that control automated dependency update behaviour.
  • Sink: The absence of a cooldown block means Dependabot's scheduler acts as an unrestricted pipeline, proposing any newly published package version without delay.
  • Missing control: No cooldown: default-days: 7 (or higher) on any ecosystem entry, and a critically short default-days: 2 on the duplicate entries that did have a cooldown.
  • CWE: CWE-1104 — Use of Unmaintained Third-Party Components (inadequate supply-chain ingestion controls).
  • Fix: Added cooldown: default-days: 7 to every package-ecosystem entry and removed duplicate entries to prevent configuration drift.

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 single missing cooldown block in a YAML file might look like a minor oversight, but in the context of software supply-chain security it represents a real and exploitable gap. This Node.js library was one fast-moving supply-chain attack away from shipping a backdoored dependency to its entire user base — not because of any flaw in the application code, but because of a misconfiguration in the automation that manages its dependencies.

The fix is simple, low-friction, and has zero impact on developer velocity: a 7-day wait before Dependabot proposes an update. That one week is the difference between your project being an early victim of a supply-chain attack and being protected by the collective vigilance of the security community.

Review your own dependabot.yml today. If you don't see a cooldown block on every package-ecosystem entry, add one.


References

Frequently Asked Questions

What is a missing Dependabot cooldown?

It means Dependabot is configured without a `cooldown` block, so it can immediately open pull requests for brand-new package versions — including ones that may be malicious, typosquatted, or unstable — with no waiting period.

How do you prevent missing Dependabot cooldown in Node.js?

Add a `cooldown` block with `default-days: 7` (or higher) to every `package-ecosystem` entry in `.github/dependabot.yml`. This tells Dependabot to wait at least seven days after a version is published before proposing it.

What CWE is missing Dependabot cooldown?

It maps most closely to CWE-1104 (Use of Unmaintained Third-Party Components) and broader software supply-chain risk categories, as it represents an inadequate control over third-party dependency ingestion.

Is a daily Dependabot schedule enough to prevent supply-chain attacks?

No. A frequent schedule (e.g., `interval: daily`) actually increases risk without a cooldown, because it maximises the chance of pulling in a malicious package the moment it is published, before anyone has reported it.

Can static analysis detect a missing Dependabot cooldown?

Yes. Semgrep rule `package_managers.dependabot.dependabot-missing-cooldown.dependabot-missing-cooldown` flags any `package-ecosystem` entry in `dependabot.yml` that lacks a `cooldown` block, making this class of misconfiguration easy to catch in CI.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #2008

Related Articles

high

How missing Dependabot cooldown happens in Node.js supply chain configuration and how to fix it

A high-severity supply chain vulnerability was discovered in a Node.js library's `.github/dependabot.yml` configuration file. The file lacked a `cooldown` block, meaning Dependabot could propose updates to newly published (and potentially malicious) package versions immediately upon release. A simple 2-line fix adding `default-days: 7` now ensures a 7-day quarantine period before any new dependency version is suggested.

high

How missing cooldown periods in Dependabot configuration happen in GitHub Actions and how to fix it

A high-severity vulnerability was discovered in a Node.js library's `.github/dependabot.yml` configuration file where no cooldown period was set for package updates. This exposed the project to potentially malicious or unstable newly-published packages, as Dependabot would immediately propose updates without any waiting period. The fix adds a 7-day cooldown to the npm package-ecosystem configuration, ensuring a safety window before adopting new package versions.

high

How missing Dependabot cooldown configuration happens in GitHub Actions and how to fix it

A high-severity vulnerability was discovered in the `.github/dependabot.yml` configuration file where no cooldown period was set for dependency updates. This exposed the Node.js library and its downstream consumers to potentially malicious or unstable packages immediately after publication. The fix adds a 7-day cooldown period to all package ecosystem entries, providing a critical safety buffer before accepting newly published package versions.

high

How missing Dependabot cooldown happens in GitHub Actions and how to fix it

A high-severity configuration flaw was discovered in a Dependabot configuration file where no cooldown period was set for package updates. This meant newly published—and potentially malicious or unstable—package versions could be immediately proposed for updates, exposing the project to supply chain attacks. The fix adds a 7-day cooldown period to allow the community to identify compromised packages before they're adopted.

high

How missing Dependabot cooldown happens in GitHub Actions CI/CD and how to fix it

A high-severity configuration gap was discovered in a Node.js library's `.github/dependabot.yml` file where no cooldown period was set for dependency updates. Without a cooldown, Dependabot could propose updates to newly published (and potentially malicious or unstable) package versions immediately after release, exposing the project and all downstream consumers to supply chain attacks. The fix adds a `cooldown` block with `default-days: 7` to each package ecosystem entry.

high

How secrets: inherit over-privilege happens in GitHub Actions reusable workflows and how to fix it

A high-severity security finding was identified in `templates/claude-workflow/workflows/claude.yml` where `secrets: inherit` passed every repository secret to a reusable workflow, violating the principle of least privilege. The fix explicitly passes only `CLAUDE_CODE_OAUTH_TOKEN`—the single secret the called workflow actually needs—drastically reducing the blast radius if the reusable workflow is ever compromised.