Skip to content
← Blog

Security research

The cooling period as defense: academic foundations

5 min read

A "cooling period" in supply-chain security is a rule that says: don't install a package version until it has been published for a minimum amount of time and accumulated a minimum number of community observations. The idea predates current tooling — it appears in academic literature on package-registry security and in operational practices at security-conscious organizations going back over a decade.

This post traces the academic foundations of the cooling-period defense and explains why the basic shape is robust to a wide range of attack patterns.

The intuition

Most supply-chain attacks that involve a compromised or malicious package version share a common structural property: the malicious version is new. Whether the attack is an account takeover, a malicious update from a maintainer who took over a package, a typosquat, or a slopsquat, the malicious bytes appear on the registry at a specific moment and either propagate quickly or sit waiting for installs.

A cooling period exploits this property. It says: regardless of why a version is new, new is the highest-risk state. Refuse to be in the first cohort of installs.

Earlier work

The concept of "deferred installation" or "version quarantine" appears in the academic literature on package-registry security from at least the early 2010s, in different forms.

Two threads of research are relevant.

Detection-window analysis. Several papers have measured the time between malicious package publication and public detection across npm, PyPI, RubyGems, and others. The findings consistently show that detection is fastest for high-profile packages and slowest for less-watched ones, with median windows in the hours and tail windows in days or weeks. The natural defensive response: introduce a delay between publication and installation that's sized against the detection window.

Reputation-based version selection. A separate strand of work proposes that consumers select package versions based on how long they have been published and how many other consumers have used them. Versions with high "consumption count" are preferred over fresh versions. This is essentially a reputation gradient over time.

The cooling-period defense as it appears in current tooling combines both ideas: a minimum publication age (detection-window-based) and a minimum observation count (reputation-based).

Why two thresholds, not one

Either threshold alone is insufficient.

Time alone fails for low-volume packages. A package that is genuinely obscure may have zero installs for the first week of a new version's life. A pure time-based threshold would auto-approve these versions even though no one has reviewed them. Time captures ecosystem-wide attention but not per-package attention.

Observation count alone fails for fast-moving popular packages. A widely-used package may accumulate hundreds of installs within minutes of a new version. A pure observation-count threshold would auto-approve a popular new version before any human has actually looked at it. Observation count captures install volume but not deliberation.

Both together capture both: the version is old enough that ecosystem-level monitoring has had a chance to flag anomalies, and enough independent installs have happened that any conditional-payload attack has had a chance to misfire on someone's machine.

How to size the thresholds

The right thresholds depend on the operational context.

For most teams, a publication age of 1–4 hours and an observation count of 5–25 covers the median attack profile without unduly disrupting legitimate releases. The defaults Veln ships with — 2 hours and 10 observations — are in this range.

Considerations when tuning:

Higher thresholds reduce risk further but increase friction on legitimate releases. A new minor version of a popular package will likely accumulate observations within minutes; the cooling delay for legitimate releases is short. For a niche internal package, observations may take longer, and a high threshold becomes operationally annoying.

Per-package thresholds can adapt. A package with a long, stable release history can be allowed shorter cooling than a package with a sporadic or recent maintenance pattern. Tooling that adjusts thresholds based on per-package history is more nuanced than a global setting.

Approval paths for time-sensitive cases. When a developer needs to install a brand-new version that's still in cooling — for example, a hotfix release minutes after an upstream emergency — an approval path lets a reviewer override the gate explicitly. The gate is a default, not an absolute.

What attacks the gate covers

A cooling gate, sized reasonably, covers:

  • Account-takeover attacks where the attacker publishes a malicious version. By the time the version exits cooling, the legitimate maintainer or community has had a chance to notice.
  • Maintainer-handoff attacks where a new maintainer publishes a malicious update. Same logic.
  • Typosquats and slopsquats. A registered-yesterday package fails the age threshold; an unobserved package fails the observation threshold. Both fire.
  • Worm propagation second-hops. The worm publishes a brand-new malicious version of a captured package. The next victim's install is in cooling, and the worm doesn't propagate.

What it does not cover

A cooling gate does not catch:

  • Long-dormant attacks: a package that was malicious from its first version, published months or years ago, and has accumulated observations and age. These are rare in practice (someone tends to notice eventually), but the gate doesn't help here.
  • Conditional payloads on observed packages: if the malicious behavior triggers only on a specific target environment, the package may have many benign observations that pass the threshold without anyone seeing the malicious branch.

These gaps are exactly why a cooling gate is one defense, not a complete solution. Consensus checks (cross-checking what you got against what others got) catch the conditional-payload case. Static analysis catches some long-dormant cases.

Takeaway

The cooling-period defense rests on a robust observation: malicious package versions are, almost by definition, new versions. Refusing to install brand-new versions until enough time and enough independent observations have accumulated raises the cost of attack across a wide class of supply-chain attacks. The thresholds are tunable; the defense itself is structural and complements other layers.