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
cooldownblock on everypackage-ecosystementry independabot.yml. GitHub's docs recommenddefault-days: 7as a sensible baseline; security-sensitive projects may want longer. - Don't rely on weekly/daily scan intervals alone. The
schedule.intervalsetting 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:10had threepackage-ecosystementries (npm/first entry, Bundler, Docker) that all lacked acooldownblock, 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-ecosystemblock needs its owncooldownentry. - 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-daysvalue on anypackage-ecosystementry, 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: 7to each of the threepackage-ecosystemblocks 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...