Back to Blog
high SEVERITY7 min read

How Supply Chain Risk from Missing Package Age Validation Happens in pnpm and How to Fix It

A pnpm workspace configuration was missing the `minimumReleaseAge` setting, creating a supply chain vulnerability where newly published (and potentially malicious) packages could be installed immediately. By adding a 10,080-minute (7-day) minimum release age to `pnpm-workspace.yaml`, the project now enforces a critical delay that allows the security community time to identify and report malicious or unstable packages before they reach production environments.

O
By Orbis AppSec
Published August 15, 2026Reviewed August 15, 2026

Answer Summary

The vulnerability is a missing supply chain security control in pnpm's workspace configuration (CWE-345: Insufficient Verification of Data Authenticity). Without the `minimumReleaseAge` setting, newly published npm packages bypass a crucial 7-day grace period that allows the security community to identify malicious code. The fix adds `minimumReleaseAge: 10080` to `pnpm-workspace.yaml`, enforcing a mandatory delay before any newly released package versions can be installed.

Vulnerability at a Glance

cweCWE-345 (Insufficient Verification of Data Authenticity)
fixAdd `minimumReleaseAge: 10080` (7 days in minutes) to pnpm-workspace.yaml
riskMalicious or unstable packages can be installed immediately after publication
languageYAML / Node.js Package Management
root causepnpm-workspace.yaml lacks minimumReleaseAge configuration setting
vulnerabilityMissing Package Release Age Validation in pnpm

How Supply Chain Risk from Missing Package Age Validation Happens in pnpm and How to Fix It

Introduction

In the pnpm-workspace.yaml configuration file of a Node.js library, a critical supply chain security control was missing: the minimumReleaseAge setting. This oversight created a window of vulnerability where malicious actors could publish compromised packages to npm, and those packages would be installed immediately by any project using this workspace configuration—before the security community had time to detect and flag the malicious code.

This isn't a code execution vulnerability in the traditional sense. Instead, it's a configuration gap that removes a crucial defense mechanism against one of the most prevalent attack vectors in modern software development: the supply chain attack through compromised or malicious npm packages.

The fix was straightforward but critical: adding four lines to pnpm-workspace.yaml to enforce a 7-day grace period before any newly published package versions can be installed. Let's explore why this matters and how to implement it in your own projects.

The Vulnerability Explained

What Happened

The original pnpm-workspace.yaml file looked like this:

packages:
  - 'packages/*'

allowBuilds:
  esbuild: true
  unrs-resolver: true

Notice what's missing: there's no settings section, and specifically, no minimumReleaseAge configuration. This means that when pnpm resolves dependencies, it will install newly published package versions immediately upon release—without any waiting period.

Why This Is Dangerous

Consider this attack scenario:

  1. An attacker compromises a popular npm package (or creates a typosquatting package with a similar name)
  2. They publish a malicious version to npm at 2:00 PM UTC
  3. Your CI/CD pipeline runs a fresh install at 2:05 PM UTC
  4. Before any security researcher, npm security team, or community member has time to analyze the package, your project has already downloaded and potentially executed the malicious code
  5. By the time the malicious package is detected and flagged (often 24-48 hours later), the damage is done

This attack pattern has been documented in real-world incidents:
- Dependency confusion attacks (like the 2021 Alex Birsan research) rely on rapid package installation
- Typosquatting campaigns depend on catching developers before they realize the mistake
- Compromised maintainer accounts can push malicious versions that spread before detection

The minimumReleaseAge setting creates a mandatory 7-day buffer that gives the security community time to:
- Analyze newly published packages
- Run security scans
- Detect anomalies in package behavior
- Report malicious packages to npm
- Allow npm to remove or yank the version

The Real-World Impact

For a Node.js library (as indicated in the PR context), this vulnerability affects all downstream consumers. If your library is used by other projects, they inherit this supply chain risk. A malicious transitive dependency could compromise not just your project, but every application that depends on your library.

The Fix

The pull request added the following configuration to pnpm-workspace.yaml:

packages:
  - 'packages/*'

allowBuilds:
  esbuild: true
  unrs-resolver: true
+
+minimumReleaseAge: 10080
+blockExoticSubdeps: true
+trustPolicy: no-downgrade

Breaking Down Each Change

1. minimumReleaseAge: 10080

This is the primary security fix. The value 10080 represents 10,080 minutes, which equals exactly 7 days. With this setting enabled:

  • pnpm will refuse to install any package version published fewer than 7 days ago
  • If a package was published on Monday, it cannot be installed until the following Monday
  • This gives the npm security community a full week to identify and report malicious packages

The 7-day window was chosen as a balance between:
- Security: Long enough for researchers to analyze packages and report issues
- Practicality: Short enough that legitimate security updates don't face unreasonable delays

2. blockExoticSubdeps: true

This complementary setting prevents pnpm from installing packages with unusual or suspicious dependency structures. It blocks:
- Packages with circular dependencies
- Packages with overly complex dependency trees
- Packages with dependencies on unregistered registries

3. trustPolicy: no-downgrade

This prevents pnpm from installing older versions of packages when newer versions are available. This protects against attacks where an attacker publishes a malicious older version (which might have fewer security checks) and tricks the package manager into downgrading.

How This Solves the Problem

Before the fix:

Package published → Immediately installable → Malicious code executes before detection

After the fix:

Package published → 7-day waiting period → Security analysis + detection → Safe installation OR version yanked

The three settings work together to create defense in depth:
1. minimumReleaseAge delays installation of new versions
2. blockExoticSubdeps prevents unusual dependency patterns
3. trustPolicy: no-downgrade prevents downgrade attacks

Prevention & Best Practices

1. Enable minimumReleaseAge in All Workspace Configurations

Add this to every pnpm-workspace.yaml:

settings:
  minimumReleaseAge: 10080

Or for individual projects using pnpm-config.yaml / .npmrc:

minimum-release-age=10080

2. Adjust the Delay Based on Your Risk Profile

While 7 days (10,080 minutes) is recommended:
- High-security environments (financial services, healthcare): Consider 14 days (20,160 minutes)
- Standard projects: Use 7 days (10,080 minutes)
- Development-only: Can use shorter delays, but production builds should use the full 7 days

3. Combine with Other Supply Chain Controls

minimumReleaseAge is one layer of defense. Combine it with:

  • Dependency pinning: Use exact versions in package-lock.json / pnpm-lock.yaml
  • Supply chain attestation: Use npm's provenance feature to verify package authenticity
  • Security scanning: Run npm audit and use tools like Snyk or Dependabot
  • Private registries: For high-security environments, mirror dependencies on a private npm registry with additional vetting
  • Signature verification: Verify package signatures where available

4. Detect Missing minimumReleaseAge with Static Analysis

Use Semgrep to automatically detect this configuration gap:

semgrep --config p/security-audit --config p/package-managers pnpm-workspace.yaml

Or specifically for this rule:

semgrep --config p/package_managers.pnpm.pnpm-missing-minimum-release-age pnpm-workspace.yaml

5. Document Your Supply Chain Policy

Add this to your project's security documentation:

## Package Installation Policy

This project enforces a 7-day minimum release age for all npm packages.
- Configured in: `pnpm-workspace.yaml`
- Setting: `minimumReleaseAge: 10080`
- Rationale: Allows security community time to identify malicious packages
- Exceptions: None. All production builds must respect this delay.

Key Takeaways

  • pnpm's minimumReleaseAge is not enabled by default, creating a supply chain vulnerability where newly published packages—potentially malicious—can be installed immediately
  • The 7-day delay (10,080 minutes) is a critical control, not a performance optimization—it's your defense against rapid supply chain attacks
  • This vulnerability affects downstream consumers: If your library lacks this setting, every project using your library inherits the risk
  • The fix is configuration-only: No code changes required, but the security impact is significant
  • Combine with defense-in-depth: Use minimumReleaseAge alongside lockfiles, security scanning, and signature verification for comprehensive supply chain protection

How Orbis AppSec Detected This

Source: The pnpm-workspace.yaml configuration file, which defines workspace-level security settings for all package installations

Sink: The missing settings.minimumReleaseAge configuration option that controls whether pnpm enforces a grace period before installing newly published packages

Missing Control: No validation that minimumReleaseAge is configured; the workspace allowed installation of packages from any release age without restriction

CWE: CWE-345 (Insufficient Verification of Data Authenticity) — the system fails to verify the trustworthiness of newly published package versions before installation

Fix: Added minimumReleaseAge: 10080 to pnpm-workspace.yaml to enforce a mandatory 7-day waiting period before any newly released package versions can be installed, allowing the security community time to identify and report malicious packages

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 is no longer optional—it's a fundamental requirement for any project that depends on third-party packages. The missing minimumReleaseAge setting in pnpm represents a common oversight: a configuration gap that removes a critical defense mechanism without adding any legitimate value.

The fix is simple (four lines of YAML), but the security impact is profound. By enforcing a 7-day grace period before package installation, you give the npm security community—and your own security team—time to identify and respond to malicious packages before they reach production.

This is especially critical for libraries and frameworks, where a single compromised dependency can affect thousands of downstream projects. Start by adding minimumReleaseAge: 10080 to your pnpm-workspace.yaml today, and encourage your dependencies to do the same.

References

  • CWE-345: Insufficient Verification of Data Authenticity — https://cwe.mitre.org/data/definitions/345.html
  • OWASP Supply Chain Security — https://owasp.org/www-community/attacks/Supply_chain_attack
  • pnpm Documentation: minimumReleaseAge Setting — https://pnpm.io/settings#minimumreleaseage
  • pnpm v10.16.0 Release Notes — https://github.com/pnpm/pnpm/releases/tag/v10.16.0
  • Semgrep Rule: pnpm Missing Minimum Release Age — https://semgrep.dev/r?q=package_managers.pnpm.pnpm-missing-minimum-release-age
  • npm Security Advisories — https://docs.npmjs.com/about-npm-advisories
  • GitHub PR: harden: this pnpm workspace configuration does not set ... in...harden: this pnpm workspace configuration does not set ... in...

Prevention and further reading

Frequently Asked Questions

What CWE applies to missing package age validation?

CWE-345 (Insufficient Verification of Data Authenticity) — the system fails to verify the trustworthiness of newly published package versions.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #16

Related Articles

critical

deleteNestedProperty Prototype Pollution via Dot-Notation Path

The `deleteNestedProperty` function in propertyUtils.ts allowed attackers to manipulate JavaScript object prototypes by passing specially crafted dot-notation paths like `__proto__.polluted`. A fix now blocks dangerous keys before processing, preventing prototype pollution attacks that could affect all objects in the application.

high

How Denial of Service via Infinite Loop Happens in JavaScript Dependencies and How to Fix It

CVE-2026-67213 is a high-severity denial of service vulnerability in nanoid before version 5.1.6 that triggers an infinite loop during random ID generation when processing specially crafted input. We upgraded nanoid across the entire dependency tree to patch this flaw and prevent attackers from freezing application threads. This fix ensures that ID generation remains resilient even when handling adversarial input patterns.

high

How Sensitive Data Exposure happens in Zotero plugins and how to fix it

A high-severity data exposure vulnerability in `Zotero.ts` automatically transmitted complete document metadata—including private notes, attachment paths, and tags—to external LLM services without user consent. The fix replaces broad `item.toJSON()` serialization with explicit field selection, sending only essential bibliographic data.

high

How missing dependency update cooldowns happen in GitHub Dependabot configurations and how to fix it

A semgrep scan flagged `.github/dependabot.yml` for lacking a cooldown period, meaning Dependabot would immediately propose updates to brand-new package versions across npm, Bundler, and Docker ecosystems. The fix adds a `cooldown: default-days: 7` block to every `package-ecosystem` entry, forcing a one-week waiting period before newly published releases are considered — reducing exposure to malicious or unstable package drops.

high

How Path Traversal Happens in TensorFlow's Data Service and How to Fix It

TensorFlow's data service dispatcher validated dataset IDs against forward-slash traversal attacks but overlooked backslash characters on non-Windows platforms, allowing attackers to escape the root directory. A targeted fix adds explicit backslash validation across all platforms, closing a high-severity path traversal vulnerability in the snapshot management system.

critical

How Unbounded WebSocket Message Handling Causes Resource Exhaustion in Node.js and How to Fix It

The WebSocketCrossServerAdapter class in a popular Node.js WebSocket library lacked any rate limiting on inbound messages, allowing attackers to flood Redis nodes and WebSocket servers with high-volume traffic. The fix introduces a configurable `rateLimit` option that caps messages per connection per second, preventing resource exhaustion while preserving legitimate functionality.