Back Original

We should all be using dependency cooldowns

Programming, philosophy, pedaling.


Nov 21, 2025     Tags: oss, security    


TL;DR: Dependency cooldowns are a free, easy, and incredibly effective way to mitigate the large majority of open source supply chain attacks. More individual projects should apply cooldowns (via tools like Dependabot and Renovate) to their dependencies, and packaging ecosystems should invest in first-class support for cooldowns directly in their package managers.


“Supply chain security” is a serious problem. It’s also seriously overhyped, in part because dozens of vendors have a vested financial interest in convincing your that their framing of the underlying problem1 is (1) correct, and (2) worth your money.

What’s consternating about this is that most open source supply chain attacks have the same basic structure:

  1. An attacker compromises a popular open source project, typically via a stolen credential or CI/CD vulnerabilty (such as “pwn requests” in GitHub Actions).

  2. The attacker introduces a malicious change to the project and uploads it somewhere that will have maximum effect (PyPI, npm, GitHub releases, &c., depending on the target).

    At this point, the clock has started, as the attacker has moved into the public.

  3. Users pick up the compromised version of the project via automatic dependency updates or a lack of dependency pinning.

  4. Meanwhile, the aforementioned vendors are scanning public indices as well as customer repositories for signs of compromise, and provide alerts upstream (e.g. to PyPI).

    Notably, vendors are incentivized to report quickly and loudly upstream, as this increases the perceived value of their services in a crowded field.

  5. Upstreams (PyPI, npm, &c.) remove or disable the compromised package version(s).

  6. End-user remediation begins.

The key thing to observe is that the gap between (1) and (2) can be very large2 (weeks or months), while the gap between (2) and (5) is typically very small: hours or days. This means that, once the attacker has moved into the actual exploitation phase, their window of opportunity to cause damage is pretty limited.

Figure: a not very scientific visualization of the phases above.

We can see this with numerous prominent supply chain attacks over the last 18 months3:

Attack Approx. Window of Opportunity References
xz-utils ≈ 5 weeks4 Source
Ultralytics (phase 1) 12 hours Source
Ultralytics (phase 2) 1 hour Source
tj-actions 3 days Source
chalk < 12 hours Source
Nx 4 hours Source
rspack 1 hour Source
num2words < 12 hours Source
Kong Ingress Controller ≈ 10 days Source
web3.js 5 hours Source

(Each of these attacks has significant downstream effect, of course, but only within their window of opportunity. Subsequent compromises from each, like Shai-Hulud, represent new windows of opportunity where the attackers regrouped and pivoted onto the next set of compromised credentials.)

My takeaway from this: some windows of opportunity are bigger, but the majority of them are under a week long. Consequently, ordinary developers can avoid the bulk of these types of attacks by instituting cooldowns on their dependencies.

Cooldowns

A “cooldown” is exactly what it sounds like: a window of time between when a dependency is published and when it’s considered suitable for use. The dependency is public during this window, meaning that “supply chain security” vendors can work their magic while the rest of us wait any problems out.

I love cooldowns for several reasons:

Concluding / assorted thoughts

In the very small sample set above, 8/10 attacks had windows of opportunity of less than a week. Setting a cooldown of 7 days would have prevented the vast majority of these attacks from reaching end users (and causing knock-on attacks, which several of these were). Increasing the cooldown to 14 days would have prevented all but 1 of these attacks6.

Cooldowns are, obviously, not a panacea: some attackers will evade detection, and delaying the inclusion of potentially malicious dependencies by a week (or two) does not fundamentally alter the fact that supply chain security is a social trust problem, not a purely technical one. Still, an 80-90% reduction in exposure through a technique that is free and easy seems hard to beat.

Related to the above, it’s unfortunate that cooldowns aren’t baked directly into more packaging ecosystems: Dependabot and Renovate are great, but even better would be if the package manager itself (as the source of ground truth) could enforce cooldowns directly (including of dependencies not introduced or bumped through automated flows).