Note on scope: This finding is a configuration hardening issue in
.github/dependabot.yml, not a code-level injection or memory bug. It falls under thepackage_managers.dependabotfamily of Semgrep rules that check dependency-update tooling for supply-chain safety controls.
Introduction
The .github/dependabot.yml file controls how GitHub's Dependabot bot proposes dependency updates for this Node.js library. Before this fix, the configuration told Dependabot to check for npm and github-actions updates weekly, but it never told Dependabot to wait before acting on what it found. That gap — a missing cooldown block — meant that the moment a new package version hit the registry, Dependabot could open a pull request recommending it, with zero buffer time for the ecosystem to notice something was wrong.
This matters more than it might seem. Supply-chain attacks increasingly rely on a narrow window: an attacker publishes a malicious version of a popular package (or compromises a maintainer's account and pushes a backdoored release), and automated tooling across thousands of repositories picks it up within hours. Projects that auto-merge Dependabot PRs, or where reviewers trust the bot's suggestions without deep scrutiny, become an easy vector. A 7-day cooldown doesn't eliminate this risk, but it dramatically shrinks the attack surface by giving the community, security researchers, and registry maintainers time to catch and pull malicious releases before your CI pipeline ever sees them.
The Vulnerability Explained
Here's the original configuration that Semgrep flagged at .github/dependabot.yml:3:
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
Notice what's absent: there is no cooldown key anywhere in either updates entry. Dependabot's default behavior, without a cooldown, is to surface any version bump it detects as soon as its weekly scan runs — including a package version that was published an hour earlier.
Why this is exploitable, concretely, for this project:
- The project depends on
npmpackages resolved from the public registry. If any transitive or direct dependency is compromised — say, a popular utility library gets a malicious patch release pushed by a hijacked maintainer account — Dependabot could open a PR proposing that exact version within the same week, before any advisory, GitHub Security Advisory, or npm takedown has happened. - The
github-actionsecosystem entry is arguably higher-risk: GitHub Actions pulled from the Marketplace run with access to repository secrets,GITHUB_TOKEN, and sometimes deploy credentials. A malicious or compromised Action version proposed and merged quickly could exfiltrate secrets or tamper with build artifacts. - Because this is a Node.js library, any compromised dependency doesn't just affect this repo's CI — it affects every downstream consumer who installs this package and inherits its dependency tree.
Example attack scenario: An attacker compromises the npm account of a mid-tier dependency used transitively by this project. They publish evil-lib@2.3.1 containing a post-install script that exfiltrates environment variables. Within the weekly Dependabot scan window, a PR titled "Bump evil-lib from 2.3.0 to 2.3.1" appears. A busy maintainer, trusting Dependabot's usual reliability, approves and merges it. CI runs npm install, the post-install script fires, and secrets leak — all before the npm security team has even flagged the package for removal. With a 7-day cooldown in place, that same PR simply wouldn't appear yet, giving the ecosystem time to catch and remove evil-lib@2.3.1 first.
The Fix
The remediation adds a cooldown block with default-days: 7 to both package-ecosystem entries — this is important, because a cooldown configured on only one ecosystem leaves the other fully exposed.
Before:
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
After:
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
cooldown:
default-days: 7
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
cooldown:
default-days: 7
With cooldown.default-days: 7 set, Dependabot will now only propose an update once a new version has existed in the registry for at least 7 days. This gives GitHub Security Advisories, npm's own abuse-detection systems, and the broader OSS community a full week to identify and yank malicious or broken releases before this repository's automated tooling ever suggests installing them.
Both entries were updated in the same PR because the vulnerability applies independently to each package-ecosystem block — cooldown is not a global setting, it's scoped per-ecosystem entry in dependabot.yml. Fixing only npm would have left github-actions — arguably the higher-privilege attack surface — unprotected.
This is a minimal, surgical change: one file, four added lines, no behavioral change to existing dependency versions or the weekly scan schedule. It only affects the timing of future update proposals.
Prevention & Best Practices
- Always set a
cooldownon everypackage-ecosystementry independabot.yml. GitHub's own documentation recommendsdefault-days: 7as a sane baseline; increase it for critical infrastructure or Actions with secret access. - Treat GitHub Actions dependencies with at least the same scrutiny as npm dependencies. Actions execute with access to
GITHUB_TOKENand often repository secrets — a compromised Action is functionally equivalent to a compromised CI credential. - Don't auto-merge Dependabot PRs blindly, even with a cooldown in place. Combine cooldown with required reviews, branch protection, and — where possible —
npm audit/npm audit signaturesin CI. - Monitor Software Bill of Materials (SBOM) and use lockfiles (
package-lock.json) so version pins are explicit and reviewable in diffs, rather than relying solely on ranges. - Scan
dependabot.ymlitself with static analysis. Semgrep'spackage_managers.dependabotruleset (used here) can catch missing cooldowns, missing schedules, and other misconfigurations automatically on every PR. - Reference GitHub's official cooldown documentation to tune
default-days,semver-major-days,semver-minor-days, andsemver-patch-daysindependently if you need finer-grained control than a single default.
Key Takeaways
.github/dependabot.ymlhad twopackage-ecosystementries (npmandgithub-actions) and neither had acooldownblock — both needed the fix, since cooldown is scoped per entry, not global.- The
github-actionsecosystem is a high-value target for this fix, since Actions run with access toGITHUB_TOKENand repo secrets. - A
cooldown.default-days: 7setting doesn't change existing pinned versions or the weekly schedule — it only delays new version proposals, so the fix is behavior-preserving for current CI. - Because this is a published Node.js library, a compromised dependency wouldn't just affect this repo's CI — it would propagate to every downstream consumer of the package.
- Static analysis (Semgrep's
dependabot-missing-cooldownrule) can catch this class of supply-chain misconfiguration automatically, before a malicious update window is ever opened.
How Orbis AppSec Detected This
- Source: GitHub's public package registries (npm registry and GitHub Actions Marketplace) — any newly published version of any dependency this repository tracks.
- Sink: Dependabot's automated pull-request creation logic, which reads
.github/dependabot.yml:3and proposes version bumps as soon asschedule.intervaltriggers. - Missing control: No
cooldownblock on eitherpackage-ecosystementry, so there was no minimum age requirement before a newly published version could be proposed for merge. - CWE: CWE-1104 (Use of Unmaintained Third-Party Components) and related supply-chain integrity risk.
- Fix: Added
cooldown: default-days: 7under both thenpmandgithub-actionspackage-ecosystementries 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 in dependabot.yml is easy to overlook because it's not a bug in application code — it's a gap in the process that decides which code gets pulled into your application. In this repository, that gap applied to both the npm dependencies powering the library and the github-actions workflows running with secret access. The fix was small — four lines, one file — but it meaningfully raises the bar for supply-chain attacks by forcing a 7-day observation window before any newly published package version is recommended for merge. If you maintain any repository with Dependabot enabled, check your dependabot.yml today: if there's no cooldown block, you're accepting brand-new, unvetted releases the moment they're published.