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

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

Answer Summary

A missing Dependabot cooldown period (CWE-1104: Use of Unmaintained Third-Party Components) in `.github/dependabot.yml` allowed Dependabot to immediately propose updates to newly published npm and GitHub Actions packages, including potentially malicious or typosquatted versions. The fix adds a `cooldown` block with `default-days: 7` to each `package-ecosystem` entry, enforcing a 7-day waiting period before Dependabot surfaces new package versions as update candidates. This is especially critical for Node.js libraries, where supply chain attacks targeting freshly published packages can cascade to all downstream consumers.

Vulnerability at a Glance

cweCWE-1104 (Use of Unmaintained Third-Party Components / Insufficient Supply Chain Controls)
fixAdded `cooldown: default-days: 7` to both ecosystem entries to enforce a 7-day waiting period before update proposals
riskAutomatic adoption of newly published, potentially malicious or unstable package versions
languageYAML (GitHub Actions / Dependabot configuration)
root causeNo `cooldown` block defined in either the `npm` or `github-actions` package ecosystem entries 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 is the heartbeat of automated dependency management in GitHub-hosted projects. It tells Dependabot which ecosystems to watch, how often to check for updates, and how to label the resulting pull requests. But a subtle omission in this file — the absence of a cooldown block — can quietly expose your project and everyone who depends on it to one of the most insidious modern threats: supply chain attacks via freshly published packages.

In this repository, a Semgrep scan flagged a high-severity misconfiguration at line 3 of .github/dependabot.yml: neither the npm ecosystem entry nor the github-actions ecosystem entry defined a cooldown period. With a schedule.interval of "daily", Dependabot was configured to surface update proposals for packages the same day they were published — before the security community, package registries, or downstream users had any opportunity to identify problems.

Because this is a Node.js library, the blast radius extends beyond the repository itself. Any downstream consumer who trusts this library's dependency updates inherits the same risk.


The Vulnerability Explained

What does "no cooldown" actually mean?

When Dependabot detects a new version of a package, the default behavior (without a cooldown) is to open a pull request almost immediately. For a repository running on a "daily" schedule, that means a package published at 11:00 PM could have an open update PR by the next morning.

Here is the vulnerable configuration as it existed before the fix:

# .github/dependabot.yml (BEFORE FIX)
version: 2
updates:
  - package-ecosystem: "npm"
    directories:
      - "/"
    schedule:
      interval: "daily"
    labels:
      - "npm"
      - "Dependabot"

  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "daily"
    labels:
      - "github-actions"
      - "Dependabot"

Notice what is absent: there is no cooldown block under either package-ecosystem entry. This is the root cause.

Why is this dangerous?

The npm ecosystem publishes thousands of new package versions every day. Not all of them are legitimate. Attackers use several well-documented techniques to exploit the window between publication and detection:

  1. Package hijacking: An attacker gains control of a maintainer's npm account and publishes a malicious version of a widely-used package. The malicious version exists for only hours before it is yanked — but that window is enough.
  2. Typosquatting / dependency confusion: A malicious package with a name similar to a legitimate one is published, hoping automated tooling will pick it up.
  3. Protestware / sabotage: A maintainer intentionally introduces destructive code into a new version (as seen with colors, faker, and node-ipc in recent years).

In all three scenarios, the first 24–72 hours after publication are the highest-risk window. Security researchers, package registry maintainers, and the broader community typically identify and flag malicious packages within days. A 7-day cooldown means Dependabot waits until after this danger window closes before ever showing the update to your team.

The attack scenario for this specific repository

Because this project runs Dependabot on a "daily" schedule for both npm packages and GitHub Actions, an attacker could:

  1. Publish a malicious patch version of any npm package listed in this project's package.json (or a GitHub Action used in its workflows).
  2. Within 24 hours, Dependabot opens a PR proposing the update.
  3. A developer, seeing a routine-looking dependency bump PR with a green CI badge, merges it.
  4. The malicious code executes in CI (for Actions) or ships to downstream consumers (for npm packages).

The github-actions ecosystem entry is particularly sensitive: a compromised GitHub Action executing in CI has access to secrets, tokens, and the ability to exfiltrate or tamper with build artifacts.


The Fix

The fix is precise and minimal: a cooldown block with default-days: 7 was added to both ecosystem entries.

# .github/dependabot.yml (AFTER FIX)
version: 2
updates:
  - package-ecosystem: "npm"
    directories:
      - "/"
    schedule:
      interval: "daily"
    cooldown:
      default-days: 7
    labels:
      - "npm"
      - "Dependabot"

  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "daily"
    cooldown:
      default-days: 7
    labels:
      - "github-actions"
      - "Dependabot"

Before vs. After

Aspect Before After
npm update proposals Immediate (same day as publish) 7 days after publish
GitHub Actions update proposals Immediate (same day as publish) 7 days after publish
Exposure to day-zero malicious packages High Significantly reduced
Lines changed +4 lines (2 per ecosystem entry)

Why both entries needed the change

It would not be sufficient to add the cooldown to only one ecosystem. Both npm and github-actions entries independently schedule Dependabot runs. An attacker targeting GitHub Actions (which run in CI with elevated permissions) would have the same zero-day window as an attacker targeting npm packages. Each ecosystem entry must independently declare its own cooldown policy.

What default-days: 7 means in practice

The cooldown.default-days value tells Dependabot: "Do not propose an update for a package version until at least N days have passed since that version was published." You can also configure per-semver-range overrides (e.g., a longer cooldown for major versions), but a 7-day default is the recommended baseline from GitHub's own documentation.


Prevention & Best Practices

1. Always define a cooldown in new Dependabot configurations

Whenever you create or update a dependabot.yml, treat cooldown.default-days as a required field, not an optional one. A value of 7 is the GitHub-recommended minimum.

2. Consider higher cooldowns for major version bumps

Major versions introduce breaking changes and are higher-risk targets for supply chain attacks. You can configure this explicitly:

cooldown:
  default-days: 7
  semver-major-days: 30

3. Combine cooldown with dependency review

GitHub's Dependency Review Action can block PRs that introduce packages with known vulnerabilities. Pairing it with a cooldown gives you both time-based and vulnerability-database-based protection.

4. Use Semgrep to enforce this in CI

The Semgrep rule package_managers.dependabot.dependabot-missing-cooldown.dependabot-missing-cooldown can be added to your CI pipeline to catch missing cooldowns before they reach production:

- name: Semgrep scan
  uses: semgrep/semgrep-action@v1
  with:
    config: >-
      p/supply-chain

5. Apply the principle of least privilege to Dependabot PRs

Ensure Dependabot PRs do not have write access to secrets. Use GitHub's Dependabot secrets feature rather than exposing repository secrets directly.

Security Standards Reference

  • OWASP A06:2021 – Vulnerable and Outdated Components: Stresses the importance of controlled, vetted dependency updates.
  • SLSA (Supply Chain Levels for Software Artifacts): Recommends verification and review windows for third-party dependencies.
  • CWE-1104: Use of Unmaintained Third-Party Components — directly applicable to unvetted, freshly published package adoption.

Key Takeaways

  • The npm ecosystem entry in .github/dependabot.yml had no cooldown, meaning any malicious npm package version could be proposed for adoption within 24 hours of publication on a daily schedule.
  • The github-actions ecosystem entry carried the same risk, and a compromised Action executing in CI is particularly dangerous due to its access to secrets and build artifacts.
  • A 4-line change — adding cooldown: default-days: 7 to each entry — closes the highest-risk window for supply chain attacks without disrupting the dependency update workflow.
  • This is a Node.js library, so the impact of a compromised dependency is not limited to this repository; it propagates to all downstream consumers.
  • Static analysis (Semgrep) can reliably detect this misconfiguration at the YAML level, making it automatable in any CI pipeline.

How Orbis AppSec Detected This

  • Source: The updates entries in .github/dependabot.yml define which package ecosystems Dependabot monitors and how quickly it acts on newly published versions.
  • Sink: The absence of a cooldown block in both the npm (line 3+) and github-actions ecosystem entries means Dependabot immediately surfaces new package versions as update candidates — the dangerous "sink" being the automated PR creation for unvetted, freshly published packages.
  • Missing control: No cooldown.default-days value was set, removing the only time-based gate between package publication and Dependabot update proposal.
  • CWE: CWE-1104 — Use of Unmaintained Third-Party Components (extended to insufficient supply chain controls over newly published versions).
  • Fix: Added cooldown: default-days: 7 to both the npm and github-actions package ecosystem entries in .github/dependabot.yml, enforcing a 7-day waiting period before any new package version is proposed as an update.

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 period in Dependabot configuration is easy to overlook — it is not a code bug, it is an absence of a safety control in a configuration file. But for a Node.js library with a daily update schedule, that absence meant every newly published package version was immediately eligible to be proposed as an update, including packages published by attackers exploiting the critical first-day window.

The fix is small: four lines of YAML. The protection it provides is substantial: a 7-day buffer that lets the security community, package registries, and automated scanners identify and flag malicious packages before they ever reach your team's review queue.

Supply chain security is not just about scanning your current dependencies — it is about controlling how and when new dependencies enter your project. Cooldown periods are one of the simplest and most effective controls available, and they should be standard practice in every dependabot.yml configuration.


References

Frequently Asked Questions

What is a Dependabot missing cooldown vulnerability?

It means your `.github/dependabot.yml` has no `cooldown` block, so Dependabot will immediately propose updates to packages the moment they are published — before the community has had time to vet them for malicious content or instability.

How do you prevent missing cooldown in Dependabot configuration?

Add a `cooldown` block with `default-days: 7` (or higher) under each `package-ecosystem` entry in your `dependabot.yml`. This tells Dependabot to wait at least 7 days after a package version is published before recommending it.

What CWE is Dependabot missing cooldown?

It maps most closely to CWE-1104 (Use of Unmaintained Third-Party Components) and broader supply chain risk categories, since the root issue is insufficient controls over which third-party package versions are automatically adopted.

Is running Dependabot with auto-merge disabled enough to prevent supply chain attacks?

Not entirely. Even without auto-merge, a missing cooldown means developers are presented with update PRs for brand-new packages immediately. Human review fatigue or urgency can lead to merging a malicious package that would have been flagged within days of publication.

Can static analysis detect a missing Dependabot cooldown?

Yes. The Semgrep rule `package_managers.dependabot.dependabot-missing-cooldown.dependabot-missing-cooldown` detects this pattern by inspecting `dependabot.yml` for `updates` entries that lack a `cooldown` block, as demonstrated in this fix.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #500

Related Articles

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.

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