Back to Blog
high SEVERITY6 min read

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

The repository's `.github/dependabot.yml` had no `cooldown` block, meaning Dependabot could open PRs to adopt a package version the moment it was published — before the ecosystem had any chance to flag it as malicious or broken. The fix adds a `cooldown.default-days: 7` setting to each `package-ecosystem` entry, forcing a one-week buffer before new releases are proposed.

O
By Orbis AppSec
Published September 7, 2026Reviewed September 7, 2026

Answer Summary

The Dependabot missing cooldown vulnerability occurs when a `.github/dependabot.yml` file lacks a `cooldown` block, causing Dependabot to immediately propose updates to brand-new package versions with no vetting window (related to CWE-1357, Reliance on Insufficiently Trustworthy Component). The fix is to add `cooldown: default-days: 7` under each `package-ecosystem` entry so newly published releases must age at least seven days before Dependabot opens an update PR, giving the community time to catch malicious or broken releases.

Vulnerability at a Glance

cweCWE-1357 (Reliance on Insufficiently Trustworthy Component)
fixAdd `cooldown: default-days: 7` to every `package-ecosystem` entry under `updates`
riskAutomated PRs can adopt a malicious or unstable package within minutes of publication
languageYAML (GitHub Dependabot configuration)
root causeNo `cooldown` block defined for `package-ecosystem` entries in `.github/dependabot.yml`
vulnerabilityDependabot missing cooldown period

Why a config file most teams never look at twice matters

.github/dependabot.yml is the kind of file a lot of teams write once and never revisit. It quietly tells GitHub which ecosystems to scan, how often, and where. But because it controls what gets automatically proposed into your codebase, it's also a prime piece of supply-chain infrastructure — and this repository's version was missing a critical safety valve: a cooldown period.

Without a cooldown block, Dependabot behaves like an eager intern who opens a PR the instant a new package version hits the registry — even if that version was published thirty seconds ago by an attacker who just took over a maintainer's npm account.

The Vulnerability Explained

Here's what a typical vulnerable .github/dependabot.yml looks like — no cooldown key anywhere:

version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "daily"
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"

There is no delay logic. As soon as GitHub's registry crawler sees a new release for any dependency tracked by these package-ecosystem entries, Dependabot opens a pull request proposing the bump — regardless of how old (or new) that release is.

That matters because the software supply chain has repeatedly shown that "newly published" and "safe" are not the same thing:

  • event-stream (2018) — a maintainer handed off the npm package to an unknown contributor who slipped in a bitcoin-wallet-stealing dependency in a minor version bump.
  • ua-parser-js (2021) — a compromised npm account pushed a malicious patch release that installed cryptominers and credential stealers on any machine that ran npm install shortly after.
  • xz-utils (2024) — a multi-year social-engineering campaign culminated in a backdoored release tag that, had it been auto-adopted by CI pipelines without delay, could have propagated a remote-code-execution backdoor across thousands of Linux builds.

In every one of these cases, the malicious version was live for hours to days before the community noticed and yanked it or published an advisory. A Dependabot config with no cooldown will happily open (and, if auto-merge is configured, merge) a PR to adopt that version during exactly that vulnerable window — long before a CVE, GHSA advisory, or npm takedown exists to stop it.

Attack scenario for this repo specifically: an attacker compromises the npm account behind a dependency used somewhere in this project's package.json, publishes a trojanized patch release, and within the daily Dependabot scan cycle a PR titled Bump <package> from x.y.z to x.y.z+1 shows up. If CI is green (the malicious payload is often designed to pass tests) and a reviewer trusts the "routine dependency bump" label enough to merge quickly, the backdoor is now in main.

The Fix

The remediation is to add a cooldown block with default-days: 7 to every package-ecosystem entry under updates:

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

With this in place, Dependabot will not propose a version that was published fewer than seven days ago. That one-week window is enough time for:

  • Security researchers and the community to spot obviously malicious releases and file advisories.
  • Package registries (npm, RubyGems, PyPI, etc.) to yank or flag compromised versions.
  • CI/telemetry from other users of the same package to surface anomalies before your repo touches it.

This fix landed as part of a broader supply-chain hardening pass in this repository. In the same effort, action/action.yml was updated to remove mutable, floating tag references from its steps:

# before — mutable tag, silently repointable by the action owner
- uses: actions/setup-node@v7
  with: { node-version: '22' }

# after — pinned to an immutable commit SHA, with the tag kept as a comment for readability
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
  with: { node-version: '22' }

The same pattern was applied to actions/upload-artifact@v7, which was pinned to 043fb46d1a93c77aae656e7c1c64a875d1fc6a0a. These two hardening changes attack the same class of risk from different angles: SHA-pinning stops an attacker from silently repointing a tag you already depend on (as happened in the tj-actions/changed-files and reviewdog incidents), while the Dependabot cooldown stops you from voluntarily adopting a brand-new, unvetted version the moment it's published. You need both — pinning without a cooldown still leaves you exposed the first time Dependabot proposes moving the pin forward to a version that's hours old.

Prevention & Best Practices

  • Always set a cooldown on every package-ecosystem entry in .github/dependabot.yml. GitHub's docs recommend default-days: 7 as a sane baseline; security-sensitive ecosystems (like github-actions, which runs with elevated CI permissions) can justify longer windows.
  • Pin GitHub Actions to full 40-character SHAs, not tags or branches, and let Dependabot bump the SHA (which is exactly what a properly cooled-down config protects you from doing prematurely).
  • Don't auto-merge Dependabot PRs blindly. Even with a cooldown, require CI plus at least a lightweight human glance at the diff for anything touching lockfiles or node_modules/vendor trees.
  • Monitor registry advisories (GitHub Security Advisories, npm's security feed, OSV) so you can react even faster than the cooldown window if something is flagged early.
  • Lint your Dependabot config as part of CI. Tools like Semgrep can parse YAML and assert that every updates[].package-ecosystem entry has a corresponding cooldown.default-days field.

Relevant standards: this class of issue maps to CWE-1357 (Reliance on Insufficiently Trustworthy Component) and is squarely in scope for the OWASP Software Supply Chain Security guidance.

Key Takeaways

  • .github/dependabot.yml in this repo had package-ecosystem entries with no cooldown block, so any freshly published version — malicious or not — could immediately trigger an update PR.
  • Adding cooldown: default-days: 7 to each ecosystem entry enforces a one-week vetting delay before Dependabot proposes new versions.
  • This complements, but does not replace, SHA-pinning of GitHub Actions (as seen in the actions/setup-node and actions/upload-artifact changes in action/action.yml) — pinning stops silent tag repointing, cooldown stops premature adoption of new releases.
  • Config-only vulnerabilities like this one are easy to miss in code review because there's no "bad line" to point at — just a missing field — which is exactly why automated scanning of .github/dependabot.yml matters.
  • A 7-day cooldown is a floor, not a ceiling: consider longer windows for github-actions and other high-privilege ecosystems.

How Orbis AppSec Detected This

  • Source: A newly published package or GitHub Action version appearing in the upstream registry (npm, RubyGems, GitHub Marketplace, etc.) that Dependabot's scanner picks up.
  • Sink: The automatically generated Dependabot pull request that proposes bumping the dependency in the project's manifest/lockfile, which CI then builds and (potentially) a maintainer merges.
  • Missing control: No cooldown block on the package-ecosystem entries in .github/dependabot.yml, so there was no minimum age requirement before a version could be proposed.
  • CWE: CWE-1357 — Reliance on Insufficiently Trustworthy Component.
  • Fix: Added a cooldown block with default-days: 7 to each package-ecosystem entry under updates in .github/dependabot.yml.

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. [Try Orbis AppSec on your repositories](https://orbisappsec.com

Frequently Asked Questions

What is a Dependabot missing cooldown vulnerability?

It's a misconfiguration where `.github/dependabot.yml` doesn't define a `cooldown` block, so Dependabot proposes updates to package versions as soon as they're published, with no time buffer to catch malicious or broken releases.

How do you prevent this in GitHub Actions / Dependabot?

Add a `cooldown` section with `default-days: 7` (or higher) to each `package-ecosystem` entry in `.github/dependabot.yml`, delaying update PRs until the new version has existed for that many days.

What CWE is associated with Dependabot missing cooldown?

CWE-1357, Reliance on Insufficiently Trustworthy Component, since the config trusts a package the instant it's published without any vetting delay.

Is pinning GitHub Actions to a SHA enough to prevent this issue?

No. SHA-pinning stops mutable-tag attacks on actions already in use, but it doesn't stop Dependabot from proposing a brand-new, unvetted version — a `cooldown` period is needed for that.

Can static analysis detect a missing Dependabot cooldown?

Yes. Semgrep-style config rules can parse `.github/dependabot.yml` and flag any `updates` entry that lacks a `cooldown.default-days` field.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #8

Related Articles

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.

critical

How Denial of Service via Gzip Bomb happens in Node.js and how to fix it

A critical Denial of Service vulnerability (CVE-2026-59873) in the `tar` npm package allowed attackers to craft malicious gzip archives that could exhaust memory or CPU during decompression. The fix upgrades `tar` from 7.5.11 to 7.5.21 across `package.json` and `package-lock.json`, closing the resource-exhaustion path without changing any application code.