Introduction
In .github/dependabot.yml, a high-severity supply chain vulnerability was lurking in plain sight. The configuration defined three package ecosystems—npm at the root directory, GitHub Actions in /.github/workflows/, and Maven at the root—but none of them included a cooldown period. This meant Dependabot could immediately propose updates to packages the moment they were published, including potentially malicious ones uploaded by attackers exploiting dependency confusion or typosquatting attacks.
This vulnerability is particularly dangerous for Java services where servlets and controllers are remotely exploitable. A compromised Maven dependency could give attackers direct access to production systems.
The Vulnerability Explained
The vulnerable configuration at line 4 of .github/dependabot.yml looked like this:
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/.github/workflows/"
schedule:
interval: "daily"
- package-ecosystem: "maven"
directory: "/"
schedule:
interval: "daily"
Notice what's missing? There's no cooldown block in any of the three package ecosystem entries. This configuration tells Dependabot to check for updates on a schedule (daily for Maven and GitHub Actions, weekly for npm), but it doesn't tell Dependabot to wait before proposing newly published versions.
The Attack Scenario
Here's how an attacker could exploit this specific configuration:
-
Reconnaissance: An attacker identifies that this Java service uses Maven dependencies with daily Dependabot checks.
-
Package Takeover or Typosquatting: The attacker publishes a malicious version of a popular library or creates a typosquatted package name similar to one in the project's
pom.xml. -
Immediate Proposal: Within 24 hours, Dependabot proposes the malicious package update as a pull request.
-
Social Engineering: The PR looks legitimate—it's from Dependabot, after all. A developer merges it during routine maintenance.
-
Compromise: The malicious code now runs in production, potentially exfiltrating secrets, creating backdoors, or compromising the Java servlet endpoints.
This attack vector is especially concerning because:
- The Maven ecosystem check runs daily, giving attackers a small window to strike
- GitHub Actions updates also run daily, meaning a compromised action could steal repository secrets
- The npm ecosystem, while weekly, still provides no protection against newly published malicious packages
The Fix
The fix adds a cooldown block with default-days: 7 to each of the three package ecosystem entries:
Before (Vulnerable)
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
After (Secure)
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
cooldown:
default-days: 7
The complete fix applies this pattern to all three ecosystems:
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
cooldown:
default-days: 7
- package-ecosystem: "github-actions"
directory: "/.github/workflows/"
schedule:
interval: "daily"
cooldown:
default-days: 7
- package-ecosystem: "maven"
directory: "/"
schedule:
interval: "daily"
cooldown:
default-days: 7
Why 7 Days?
The 7-day cooldown period is significant because:
- Community Detection Time: Most malicious packages are discovered and reported within a week of publication
- Registry Response Time: Package registries like npm and Maven Central typically remove malicious packages within days of reports
- Balance: 7 days provides protection without significantly delaying legitimate security updates
Each ecosystem needed the fix because:
- npm: JavaScript dependencies are frequent targets for supply chain attacks
- github-actions: Compromised actions can steal repository secrets and credentials
- maven: Java dependencies have direct access to production code execution
Prevention & Best Practices
1. Always Configure Cooldown Periods
Every package-ecosystem entry in your dependabot.yml should include:
cooldown:
default-days: 7
For critical production systems, consider increasing this to 14 or even 30 days.
2. Implement Additional Dependabot Security Settings
updates:
- package-ecosystem: "maven"
directory: "/"
schedule:
interval: "daily"
cooldown:
default-days: 7
# Additional security measures
open-pull-requests-limit: 5
reviewers:
- "security-team"
labels:
- "dependencies"
- "security-review"
3. Use Dependency Scanning Tools
Complement Dependabot with tools that verify package integrity:
- GitHub's dependency review action
- Snyk or Dependabot security alerts
- OSSF Scorecard for supply chain risk assessment
4. Enforce Code Review for Dependency Updates
Never auto-merge Dependabot PRs. Require at least one approval from a security-aware team member.
5. Monitor for Suspicious Packages
Set up alerts for:
- Newly published packages matching your dependencies
- Major version jumps in minor updates
- Packages with sudden ownership changes
Key Takeaways
- The
.github/dependabot.ymlfile had zero cooldown protection across npm, GitHub Actions, and Maven ecosystems—all three were vulnerable to immediate malicious package proposals - Daily Maven and GitHub Actions checks created a 24-hour attack window where malicious packages could be proposed immediately after publication
- A 7-day cooldown is the minimum recommended protection—this gives the security community time to identify and report malicious packages
- Each
package-ecosystementry needs its owncooldownblock—there's no global setting that applies to all ecosystems - Supply chain attacks are increasingly common—the SolarWinds, Codecov, and ua-parser-js incidents demonstrate the real-world impact of dependency compromise
How Orbis AppSec Detected This
- Source: Package registry (npm, Maven Central, GitHub Actions marketplace) publishing newly released package versions
- Sink: Dependabot's automatic pull request creation at
.github/dependabot.ymlconfiguration - Missing control: No
cooldownblock withdefault-daysvalue in any of the threepackage-ecosystementries - CWE: CWE-829 (Inclusion of Functionality from Untrusted Control Sphere)
- Fix: Added
cooldown: default-days: 7to all three package ecosystem configurations (npm, github-actions, maven)
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
This vulnerability demonstrates that security isn't just about the code you write—it's also about how you configure your development tools. A missing cooldown period in Dependabot configuration created a supply chain attack vector that could have led to malicious code running in production.
The fix was straightforward: add a 7-day cooldown to each package ecosystem. But the lesson is broader: always review your CI/CD configurations with a security mindset. Automated tools like Dependabot are powerful allies, but they need proper guardrails to avoid becoming attack vectors themselves.
For Java services with remotely exploitable endpoints, supply chain security is critical. A compromised dependency doesn't just affect your code—it affects every user who interacts with your application.