Back to Blog
high SEVERITY6 min read

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.

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

Answer Summary

This is a supply-chain configuration weakness (CWE-1357, Reliance on Insufficiently Trustworthy Component) in a GitHub Dependabot YAML file that lacked a `cooldown` setting, causing Dependabot to immediately suggest updates to freshly published package versions. The fix adds `cooldown: default-days: 7` to each `package-ecosystem` block in `.github/dependabot.yml`, delaying automated update proposals by seven days so newly released — and potentially compromised — versions can be vetted by the community first.

Vulnerability at a Glance

cweCWE-1357 (Reliance on Insufficiently Trustworthy Component)
fixAdded `cooldown: default-days: 7` to every `package-ecosystem` entry (bundler, docker, and the third ecosystem) so updates wait 7 days before being proposed
riskAutomated adoption of newly-published, potentially malicious or unstable dependency versions
languageYAML / GitHub Dependabot configuration
root cause`package-ecosystem` entries in `.github/dependabot.yml` had no `cooldown` block, so updates were proposed the instant a new version was published
vulnerabilityMissing Dependabot Cooldown Period (Supply Chain Risk)

Introduction

This fix landed in .github/dependabot.yml:10, flagged by semgrep's package_managers.dependabot.dependabot-missing-cooldown.dependabot-missing-cooldown rule as a HIGH severity finding. The configuration was functionally correct — it scheduled weekly dependency checks for three package ecosystems — but it was missing a cooldown block on every package-ecosystem entry. That single omission meant Dependabot would open pull requests for a new dependency version the moment it was published on npm, RubyGems, or Docker Hub, with zero delay for the community to notice something was wrong.

If you maintain CI/CD pipelines or dependency automation for any repository, this is worth understanding: cooldown periods aren't a nice-to-have, they're a direct mitigation against a well-documented class of supply-chain attacks where malicious code is slipped into a package and yanked within hours — but not before automated tooling has already merged it.

The Vulnerability Explained

Here's what .github/dependabot.yml looked like before the fix, condensed to show the pattern repeated across all three ecosystems:

updates:
  - package-ecosystem: "npm"        # (or equivalent — first entry)
    directory: "/"
    schedule:
      interval: "weekly"

  # Maintain dependencies for Bundler
  - package-ecosystem: "bundler"
    directory: "/"
    schedule:
      interval: "weekly"

  # Maintain dependencies for Docker
  - package-ecosystem: "docker"
    directory: "/"
    schedule:
      interval: "weekly"

Each updates entry tells Dependabot how often to scan for new versions (interval: "weekly"), but says nothing about when a newly published version becomes eligible to be proposed. Without a cooldown block, GitHub's default behavior is to treat a package as fair game the instant it appears in the registry — no matter how many hours or minutes old it is.

That's a problem because npm, RubyGems, and Docker Hub all have well-known histories of compromised maintainer accounts publishing malicious versions of legitimate packages (typosquatting, credential-stealing postinstall scripts, cryptominers baked into base images, etc.). These packages are typically caught and pulled within hours to a few days — but a Dependabot run that fires the same day the malicious version is published can open a PR for it before anyone has flagged it. If auto-merge is enabled anywhere downstream, or a reviewer approves the PR without double-checking the changelog, that malicious version ships straight into the codebase.

Example attack scenario: An attacker compromises a maintainer's npm token and publishes some-dependency@2.4.1 with an obfuscated post-install script that exfiltrates environment variables. Because this repo's dependabot.yml had no cooldown, the weekly scan picks up 2.4.1 immediately and opens a PR titled "Bump some-dependency from 2.4.0 to 2.4.1." A reviewer skimming the diff sees a routine patch bump and merges it. Twelve hours later the package is pulled from npm for being malicious — but by then it's already in the dependency tree.

The Fix

The fix, taken directly from the diff, adds a cooldown block with default-days: 7 to every package-ecosystem entry in .github/dependabot.yml:

     directory: "/"
     schedule:
       interval: "weekly"
+    cooldown:
+      default-days: 7

   # Maintain dependencies for Bundler
   - package-ecosystem: "bundler"
     directory: "/"
     schedule:
       interval: "weekly"
+    cooldown:
+      default-days: 7

   # Maintain dependencies for Docker
   - package-ecosystem: "docker"
     directory: "/"
     schedule:
       interval: "weekly"
+    cooldown:
+      default-days: 7

With this change, Dependabot now waits seven days after a version is published before it becomes eligible to be proposed as an update — for the npm/first ecosystem, Bundler, and Docker entries alike. Concretely, if some-dependency@2.4.1 is published today, Dependabot won't open a PR for it until the same version has been live for a full week. That window gives the ecosystem time to detect and yank malicious releases (as happened in the scenario above) before this repository's automation ever touches it.

Each of the three ecosystems needed the same fix independently, because cooldown is configured per package-ecosystem block in Dependabot's schema — there's no global setting that applies to all entries at once. Skipping any one block would leave that ecosystem exposed even after the other two were patched.

Prevention & Best Practices

  • Always set a cooldown block on every package-ecosystem entry in dependabot.yml. GitHub's docs recommend default-days: 7 as a sensible baseline; security-sensitive projects may want longer.
  • Don't rely on weekly/daily scan intervals alone. The schedule.interval setting controls how often Dependabot checks, not how fresh a version needs to be — those are separate controls and both matter.
  • Pair cooldowns with review gates. Even with a cooldown, require human review (or at minimum, a CI security scan) before merging dependency bump PRs rather than enabling blanket auto-merge.
  • Scan your dependency automation configs, not just your application code. Tools like semgrep now ship rules specifically for dependabot.yml (e.g., package_managers.dependabot.dependabot-missing-cooldown), catching supply-chain misconfigurations before they become incidents.
  • Track CWE-1357 (Reliance on Insufficiently Trustworthy Component) as part of your supply-chain threat model — it covers exactly this class of issue, where automation trusts an external component without sufficient vetting delay.

Key Takeaways

  • .github/dependabot.yml:10 had three package-ecosystem entries (npm/first entry, Bundler, Docker) that all lacked a cooldown block, meaning every one of them was exposed to zero-delay malicious package adoption.
  • The fix is a pure configuration change — cooldown: default-days: 7 — with no application code touched, but it materially reduces the window in which a freshly compromised package version can be auto-proposed for merge.
  • Cooldowns must be added per-ecosystem; there's no single global switch, so each package-ecosystem block needs its own cooldown entry.
  • This finding was caught by semgrep's dedicated Dependabot rule set, showing that infrastructure-as-code and CI/CD configs deserve the same static analysis scrutiny as application source.

How Orbis AppSec Detected This

  • Source: New package versions published to npm/RubyGems/Docker Hub registries, ingested by Dependabot's weekly scan
  • Sink: Automatic pull request creation for dependency updates, configured in .github/dependabot.yml:10
  • Missing control: No cooldown.default-days value on any package-ecosystem entry, so no vetting delay existed before a new version could be proposed
  • CWE: CWE-1357 (Reliance on Insufficiently Trustworthy Component)
  • Fix: Added cooldown: default-days: 7 to each of the three package-ecosystem blocks 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 setting in dependabot.yml is easy to overlook because it doesn't break anything — the automation still runs, PRs still get opened, tests still pass. But that's exactly what makes it dangerous: it silently removes a built-in safety margin against supply-chain attacks. By adding cooldown: default-days: 7 to each of the three package-ecosystem entries in this repository's Dependabot config, the fix ensures that newly published versions get a week to prove themselves safe before they're proposed for merge. It's a small YAML change with an outsized impact on the trustworthiness of automated dependency updates — treat your CI/CD and dependency-management configs with the same scrutiny you'd give application code.

References

  • CWE-1357: Reliance on Insufficiently Trustworthy Component — https://cwe.mitre.org/data/definitions/1357.html
  • GitHub Docs — Dependabot cooldown configuration option — https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#cooldown
  • OWASP Software Supply Chain Security Cheat Sheet — https://cheatsheetseries.owasp.org/cheatsheets/Software_Supply_Chain_Security_Cheat_Sheet.html
  • Semgrep rule reference — https://semgrep.dev/r?q=dependabot-missing-cooldown
  • fix: this dependabot configuration does not set a co... in...

Frequently Asked Questions

What is a Dependabot missing cooldown vulnerability?

It's a supply-chain security gap where a `dependabot.yml` file has no `cooldown` setting, so Dependabot opens pull requests for dependency updates the moment a new version is published, with no buffer period to catch compromised or buggy releases.

How do you prevent this in GitHub Dependabot configurations?

Add a `cooldown` block with a `default-days` value (commonly 7) under each `package-ecosystem` entry in `dependabot.yml`, which tells Dependabot to wait that many days after a version is published before proposing it.

What CWE applies to missing cooldown periods in dependency automation?

CWE-1357 (Reliance on Insufficiently Trustworthy Component) is the closest fit, since the configuration trusts freshly-published package versions without any vetting window.

Is a 7-day cooldown enough to prevent malicious package updates?

It significantly reduces risk by giving the community time to flag malicious or broken releases (many supply-chain attacks are caught within days), but it should be paired with other controls like SBOM review, package pinning, and CI security scanning rather than relied on alone.

Can static analysis detect missing Dependabot cooldown configuration?

Yes — semgrep's `package_managers.dependabot.dependabot-missing-cooldown` rule specifically scans `dependabot.yml` files for `package-ecosystem` entries that lack a `cooldown` block and flags them automatically.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #67

Related Articles

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.

high

How Command Injection Happens in Node.js child_process and How to Fix It

A high-severity command injection vulnerability was discovered in `server.js` where user-controlled file paths were passed directly to shell commands via `exec()`. By migrating from `exec()` to `execFile()` and using argument arrays instead of string concatenation, the fix eliminates the attack surface while preserving the intended trash/delete functionality across macOS, Windows, and Linux.