How Missing Dependabot Cooldown Periods Happen in GitHub Actions and How to Fix Them
The Incident: A Two-Line Gap in dependabot.yml
In the octicons_react library — part of GitHub's own Primer design system — a static analysis scan flagged a high-severity finding in .github/dependabot.yml at line 8. The issue wasn't a buffer overflow or an injection flaw. It was the absence of two lines of configuration that left the project's automated dependency update pipeline without a critical safety gate: a cooldown period.
Without a cooldown block, Dependabot would immediately open pull requests proposing updates the moment a new package version was published to the npm registry — no waiting, no community review window, no time for security researchers to flag a malicious release. For a library like octicons_react that is consumed by thousands of downstream projects, this represents a meaningful supply chain risk.
The Vulnerability Explained
What Is a Dependabot Cooldown, and Why Does Its Absence Matter?
Dependabot automates dependency updates by monitoring package registries and opening pull requests when new versions are available. This is enormously useful — but it creates a subtle risk: newly published packages are the most dangerous window for supply chain attacks.
Attackers who compromise a maintainer's npm account, publish a typosquatted package, or inject malicious code into a legitimate release rely on the short window between publication and detection. During this window:
- Security researchers haven't yet audited the new version
- The npm security team hasn't had time to respond to reports
- Automated scanners (like Dependabot's own vulnerability database) haven't updated their advisories
Without a cooldown, Dependabot can surface a malicious package version within minutes of it being published — and an automated merge policy or an inattentive reviewer could land that malicious code in production.
The Vulnerable Configuration
Here is the relevant section of .github/dependabot.yml before the fix:
updates:
- package-ecosystem: "npm"
directory: "/docs"
schedule:
interval: "daily"
allow:
- dependency-name: "@primer/gatsby-theme-doctocat"
labels:
Notice what's missing: there is no cooldown block between the schedule entry and the allow block. This means that when the daily schedule fires, Dependabot will immediately propose any newly published version of @primer/gatsby-theme-doctocat — even if it was published hours ago.
A Concrete Attack Scenario
Consider this realistic attack chain targeting this exact configuration:
- An attacker compromises the npm credentials of a maintainer of
@primer/gatsby-theme-doctocat. - At 11:58 PM, the attacker publishes a malicious patch version (e.g.,
5.0.1) that exfiltrates environment variables during the build process. - At midnight, Dependabot's daily schedule fires for the
/docsdirectory. - By 12:05 AM, Dependabot has opened a PR titled "Bump @primer/gatsby-theme-doctocat from 5.0.0 to 5.0.1."
- An automated merge bot (or a tired developer) approves the PR.
- The malicious package runs during the next CI build, exfiltrating
NPM_TOKEN,GITHUB_TOKEN, or other secrets from the build environment. - The npm security team flags the malicious version at 9:00 AM — too late.
A 7-day cooldown would have blocked step 4 entirely, giving the security community 168 hours to detect and report the compromise before it could reach any consumer.
Connection to the sharp / libvips CVEs
This configuration issue is directly connected to the reported CVEs in lib/octicons_react/yarn.lock — specifically CVE-2026-33327, CVE-2026-33328, CVE-2026-35590, and CVE-2026-35591 in sharp's inherited libvips dependency. The absence of a cooldown means that even well-intentioned dependency updates could land vulnerable transitive dependencies in the project before the security community has had time to assess them. A cooldown period is a first-line defense against exactly this class of inherited vulnerability.
The Fix
What Changed
The fix adds exactly two lines to .github/dependabot.yml:
cooldown:
default-days: 7
Here is the complete before/after diff:
Before:
updates:
- package-ecosystem: "npm"
directory: "/docs"
schedule:
interval: "daily"
allow:
- dependency-name: "@primer/gatsby-theme-doctocat"
After:
updates:
- package-ecosystem: "npm"
directory: "/docs"
schedule:
interval: "daily"
cooldown:
default-days: 7
allow:
- dependency-name: "@primer/gatsby-theme-doctocat"
Why This Specific Change Solves the Problem
The cooldown block instructs Dependabot to only propose updates for package versions that were published at least 7 days ago. This single configuration change:
- Creates a community review window: 7 days is enough time for npm's security team, automated malware scanners, and the open-source community to identify and report a malicious release.
- Filters out unstable releases: New package versions often introduce regressions that are caught and patched within days. A cooldown naturally filters out these short-lived unstable versions.
- Reduces alert fatigue: Projects that publish frequently (e.g., multiple patch versions per week) won't flood maintainers with Dependabot PRs for each micro-release.
- Does not disable automation: The fix preserves the full benefit of Dependabot's automated updates — it simply adds a trust delay rather than disabling updates entirely.
The default-days: 7 value is GitHub's own recommended baseline. For higher-risk environments or packages with a history of supply chain incidents, this value can be increased to 14 or 30 days.
Prevention & Best Practices
Always Define a Cooldown in Every package-ecosystem Entry
A dependabot.yml file can contain multiple package-ecosystem entries (e.g., npm, pip, bundler, docker). The cooldown must be defined per entry — a single global cooldown does not exist in the current Dependabot configuration schema. Audit every entry in your configuration file:
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
cooldown:
default-days: 7 # ✅ Required for each entry
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
cooldown:
default-days: 7 # ✅ Also required here
Use Per-Dependency Cooldown Overrides for Critical Packages
For packages that are particularly sensitive (e.g., authentication libraries, cryptographic packages, build tooling), consider extending the cooldown beyond the default:
cooldown:
default-days: 7
semver-patch-days: 3 # Shorter wait for patch versions
semver-minor-days: 7 # Standard wait for minor versions
semver-major-days: 14 # Longer wait for major versions
Enforce Code Review on All Dependabot PRs
A cooldown period is not a substitute for human review. Configure branch protection rules to require at least one reviewer approval before merging any Dependabot PR:
# .github/CODEOWNERS
/package.json @security-team
/yarn.lock @security-team
Combine with Dependency Review Action
Use GitHub's dependency-review-action in your CI pipeline to block PRs that introduce known-vulnerable packages:
# .github/workflows/dependency-review.yml
- name: Dependency Review
uses: actions/dependency-review-action@v4
with:
fail-on-severity: high
Detect This Pattern with Semgrep
The Semgrep rule that caught this issue can be run locally or in CI:
semgrep --config "p/supply-chain" .github/dependabot.yml
The specific rule ID is:
package_managers.dependabot.dependabot-missing-cooldown.dependabot-missing-cooldown
Relevant Standards
- CWE-1357: Reliance on Insufficiently Trustworthy Component
- OWASP A06:2021: Vulnerable and Outdated Components
- SLSA Supply Chain Levels: A cooldown period supports SLSA L2+ requirements for verified build dependencies
Key Takeaways
- The absence of two lines in
.github/dependabot.ymlleftocticons_reactexposed to supply chain attacks via immediately-proposed updates from newly published npm packages — no code change was required to introduce the risk. - A 7-day cooldown directly mitigates the malicious-package publication attack vector by ensuring no version younger than one week is ever automatically proposed, giving the security community time to respond.
- The
cooldownblock must be added to everypackage-ecosystementry individually — there is no global default in Dependabot's configuration schema, so a single missing entry is enough to leave a gap. - The
sharp/libvipsCVEs (CVE-2026-33327, CVE-2026-33328, CVE-2026-35590, CVE-2026-35591) inyarn.lockillustrate exactly why this matters: transitive vulnerabilities can arrive via automated dependency updates, and a cooldown is the first gate that slows their propagation. - Static analysis tools like Semgrep can detect this class of misconfiguration automatically — making it feasible to enforce cooldown policies across an entire organization's repositories at scale.
How Orbis AppSec Detected This
- Source: The
.github/dependabot.ymlconfiguration file at line 8, which defines thenpmpackage-ecosystem update policy for the/docsdirectory. - Sink: Dependabot's automated PR creation pipeline — specifically, the absence of a
cooldownblock means newly published npm packages flow directly into proposed dependency updates without any time-based trust gate. - Missing control: No
cooldown: default-days: Nblock was present under thenpmpackage-ecosystem entry, meaning Dependabot applied zero waiting period before proposing updates from freshly published package versions. - CWE: CWE-1357 — Reliance on Insufficiently Trustworthy Component
- Fix: Added
cooldown: default-days: 7between thescheduleandallowblocks in.github/dependabot.ymlto enforce a 7-day waiting period before any new npm 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
The missing cooldown block in octicons_react's .github/dependabot.yml is a textbook example of how security risk can live entirely in configuration files — no application code, no user input, no cryptographic flaw. Two lines of YAML were the difference between a dependency pipeline that blindly trusts the npm registry at the moment of publication and one that waits for the security community to do its job.
For developers maintaining Node.js libraries — especially those with downstream consumers — Dependabot cooldown periods are a non-negotiable part of a responsible supply chain posture. The fix is trivial; the protection it provides is substantial. Audit your own .github/dependabot.yml files today and add cooldown: default-days: 7 to every package-ecosystem entry you find.