How Missing Dependabot Cooldown Happens in GitHub Actions CI/CD and How to Fix It
Introduction
In a containerized service repository, we discovered a high-severity supply chain vulnerability at line 3 of .github/dependabot.yml. The configuration defined two package ecosystem entries—npm and github-actions—both with weekly update schedules but no cooldown period. This meant Dependabot would immediately propose updates to any newly published package version, regardless of how recently it was released.
This is particularly dangerous because supply chain attacks frequently exploit the window between when a malicious package is published and when it's discovered and removed. Without a cooldown, your automated tooling becomes the attacker's delivery mechanism.
Here's the vulnerable configuration:
version: 2
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
Notice the complete absence of any cooldown block in either ecosystem entry. Both npm packages and GitHub Actions are proposed for update the moment a new version appears on the registry.
The Vulnerability Explained
What's Actually Happening
Dependabot's cooldown feature was introduced specifically to address supply chain timing attacks. When a package is newly published to npm or a GitHub Action is updated, there's an inherent risk period. Malicious actors frequently:
- Typosquat popular packages and publish malicious versions
- Compromise maintainer accounts and push backdoored releases
- Publish dependency confusion packages targeting internal package names
Without a cooldown, Dependabot will create a pull request proposing the update within its next scheduled run (in this case, weekly). If a developer merges that PR without careful review—especially in a fast-moving CI/CD pipeline—the malicious code enters production.
A Concrete Attack Scenario
Consider this timeline for the vulnerable configuration:
- Monday 2:00 AM: Attacker publishes a compromised version of a dependency used in this project's
package.json - Monday 3:00 AM: Dependabot's weekly scan runs, detects the "update," and opens a PR
- Monday 9:00 AM: A developer sees the Dependabot PR, CI passes (the malicious payload is designed to evade tests), and merges it
- Monday 9:05 AM: The containerized service deploys with the compromised dependency
- Tuesday: The npm security team identifies and removes the malicious package—but the damage is done
With a 7-day cooldown, Dependabot would not have proposed this update until the following Monday, by which time the malicious package would have been flagged and removed from the registry.
Why Both Ecosystems Matter
The github-actions ecosystem is equally vulnerable. Compromised GitHub Actions can:
- Exfiltrate secrets and tokens from CI/CD environments
- Inject malicious code into build artifacts
- Modify deployment pipelines to include backdoors
Since this is a containerized service, a compromised build step could inject malware directly into the container image.
The Fix
The fix adds a cooldown block with default-days: 7 to both package ecosystem entries in .github/dependabot.yml:
Before:
version: 2
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
After:
version: 2
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
cooldown:
default-days: 7
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
cooldown:
default-days: 7
How This Solves the Problem
The cooldown configuration tells Dependabot: "Do not propose an update to any package version that was published less than 7 days ago." This creates a critical buffer period where:
- Community detection: Security researchers, automated scanners, and the broader community have time to identify malicious packages
- Registry response: npm and GitHub have time to remove compromised packages
- Stability verification: Unstable releases that introduce breaking changes are often yanked or patched within days
The 7-day default is significant—research shows that the vast majority of malicious packages are identified and removed within 72 hours of publication, making a 7-day window extremely effective at filtering out supply chain attacks.
Why Both Entries Need the Fix
Each package-ecosystem entry operates independently. Adding cooldown only to the npm entry would leave github-actions unprotected. Since GitHub Actions have direct access to repository secrets, CI/CD credentials, and deployment pipelines, they represent an equally critical attack surface.
Prevention & Best Practices
1. Always Configure Cooldown Periods
Every dependabot.yml should include cooldown periods. For high-security environments, consider extending beyond 7 days:
cooldown:
default-days: 14
2. Combine with Version Pinning
For GitHub Actions specifically, pin to exact commit SHAs rather than version tags:
# Vulnerable to tag manipulation
- uses: actions/checkout@v4
# Pinned to immutable commit SHA
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
3. Enable Dependabot Security Advisories
Cooldown works alongside Dependabot's security advisory integration. Known-vulnerable versions are still flagged immediately, while the cooldown only applies to routine version bumps.
4. Use Dependency Review Actions
Add actions/dependency-review-action to your CI pipeline to block PRs that introduce known-vulnerable dependencies, even if they pass the cooldown period.
5. Implement SLSA Framework
For containerized services, adopt Supply-chain Levels for Software Artifacts (SLSA) to verify the provenance of all dependencies.
Key Takeaways
- A missing
cooldownblock independabot.ymlturns your automated dependency management into a supply chain attack vector — Dependabot proposes malicious packages before the community can flag them - Both
npmandgithub-actionsecosystems in this configuration were vulnerable — each ecosystem entry needs its own cooldown block; they don't inherit from each other - 7 days is the minimum effective cooldown — most malicious packages are identified within 72 hours, so 7 days provides substantial margin
- Containerized services amplify the risk — a compromised dependency in a container build can persist in production images even after the malicious source package is removed
- This is a configuration-only fix with zero performance impact — adding
cooldown: default-days: 7has no downside other than slightly delayed non-critical updates
How Orbis AppSec Detected This
- Source: Newly published package versions on npm registry and GitHub Actions marketplace
- Sink: Dependabot's automated PR creation in
.github/dependabot.ymlecosystem entries at lines 3-6 and 7-10 - Missing control: No
cooldownblock configured to delay adoption of newly published versions - CWE: CWE-1104 (Use of Unmaintained Third Party Components)
- Fix: Added
cooldown: default-days: 7to both thenpmandgithub-actionspackage ecosystem entries independabot.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
Supply chain security isn't just about scanning your code—it's about how you adopt new dependencies. A missing cooldown period in Dependabot configuration is a subtle but high-impact vulnerability that turns your automation against you. By adding a simple 7-day cooldown to each ecosystem entry in .github/dependabot.yml, you create a critical buffer that prevents your CI/CD pipeline from being the first adopter of potentially malicious package versions.
The fix is trivial—four lines of YAML per ecosystem entry—but the protection it provides against supply chain attacks like those seen in the event-stream, ua-parser-js, and colors.js incidents is substantial. Every repository using Dependabot should audit its configuration for this setting today.
References
- CWE-1104: Use of Unmaintained Third Party Components
- GitHub Dependabot Cooldown Documentation
- OWASP Software Component Verification Standard
- Semgrep Dependabot Rules
- fix: this dependabot configuration does not set a co... in... — Pull Request with the applied fix
- SLSA Supply Chain Security Framework