Back to Blog
high SEVERITY6 min read

How package_managers.pnpm.pnpm-missing-minimum-release-age.pnpm-minimum-release-age happens in pnpm and how to fix it

A pnpm workspace configuration in `site-astro/pnpm-workspace.yaml` was missing critical supply chain security settings including `minimumReleaseAge`, `trustPolicy`, and `blockExoticSubdeps`. Without these protections, the project could install freshly published malicious packages within minutes of their release. The fix adds a 7-day quarantine period, downgrade protection, and exotic subdependency blocking.

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

Answer Summary

The pnpm-missing-minimum-release-age vulnerability (CWE-829) occurs when a pnpm workspace configuration lacks the `minimumReleaseAge` setting, allowing freshly published (potentially malicious) npm packages to be installed immediately. In pnpm v10.16.0+, this is fixed by adding `minimumReleaseAge: 10080` to `pnpm-workspace.yaml`, which enforces a 7-day waiting period before new package versions can be installed, giving the community time to detect compromised releases.

Vulnerability at a Glance

cweCWE-829 (Inclusion of Functionality from Untrusted Control Sphere)
fixAdded `minimumReleaseAge: 10080`, `trustPolicy: no-downgrade`, and `blockExoticSubdeps: true`
riskInstallation of freshly published malicious or compromised npm packages
languageYAML (pnpm configuration)
root causepnpm-workspace.yaml lacked minimumReleaseAge, trustPolicy, and blockExoticSubdeps settings
vulnerabilityMissing minimum release age in pnpm workspace configuration

Introduction

In the site-astro project, we discovered a high severity supply chain security misconfiguration in pnpm-workspace.yaml. The workspace configuration file — responsible for governing how pnpm resolves and installs dependencies for an Astro-based website — was missing three critical security hardening settings. Most notably, the absence of minimumReleaseAge meant that any freshly published npm package version could be pulled into the project immediately, before the community had any chance to identify if it was compromised.

This matters because supply chain attacks on npm are not theoretical. The event-stream, ua-parser-js, and colors incidents demonstrated that attackers routinely publish malicious versions of popular packages. Without a quarantine period, automated dependency updates (or even manual pnpm update commands) could pull in a compromised package within minutes of its publication.

The Vulnerability Explained

What Was Missing

The original site-astro/pnpm-workspace.yaml contained only a basic configuration:

onlyBuiltDependencies:
  - esbuild
  - sharp
catalog:
  astro: ^5.16.0

This configuration tells pnpm which packages are allowed to run build scripts (esbuild and sharp) and defines a version catalog for Astro. However, it's missing three security-critical settings that pnpm v10.16.0+ supports:

  1. minimumReleaseAge — No quarantine period for newly published packages
  2. trustPolicy — No protection against security setting downgrades
  3. blockExoticSubdeps — No blocking of unusual transitive dependencies

How This Could Be Exploited

Consider this attack scenario specific to this project:

  1. An attacker identifies that site-astro depends on astro: ^5.16.0 (visible in the catalog)
  2. The attacker compromises the npm credentials of a maintainer of any package in Astro's dependency tree
  3. They publish a malicious patch version (e.g., bumping a transitive dependency from 1.2.3 to 1.2.4)
  4. A developer on the site-astro project runs pnpm update — the malicious version is installed immediately
  5. The malicious code executes during the build process (since esbuild and sharp already have build script permissions)

Without minimumReleaseAge, there's zero delay between publication and potential installation. Most supply chain attacks are detected within hours to days — a 7-day quarantine would catch the vast majority.

The Compounding Risk

The missing trustPolicy: no-downgrade setting compounds this risk. An attacker who gains partial control could potentially downgrade security settings in the lockfile, removing protections that were previously in place. The missing blockExoticSubdeps: true means transitive dependencies could introduce unusual package sources that bypass normal npm registry vetting.

The Fix

The fix adds three lines to site-astro/pnpm-workspace.yaml, inserting them between the onlyBuiltDependencies list and the catalog section:

Before

onlyBuiltDependencies:
  - esbuild
  - sharp
catalog:
  astro: ^5.16.0

After

onlyBuiltDependencies:
  - esbuild
  - sharp
trustPolicy: no-downgrade
blockExoticSubdeps: true
minimumReleaseAge: 10080
catalog:
  astro: ^5.16.0

What Each Setting Does

minimumReleaseAge: 10080 — The value 10080 is in minutes, which equals exactly 7 days. pnpm will refuse to install any package version that was published less than 7 days ago. This gives the security community time to detect and report compromised packages before they reach your project.

trustPolicy: no-downgrade — Prevents the lockfile from having its security settings downgraded. If a malicious actor modifies the lockfile (e.g., via a compromised CI pipeline or a deceptive PR), pnpm will reject changes that weaken security posture. This was added in pnpm v10.21.0.

blockExoticSubdeps: true — Blocks transitive dependencies that come from unusual sources (git repositories, tarballs, etc.) rather than the standard npm registry. This prevents attackers from sneaking in unvetted code through deep dependency chains.

Why This Is Behavior-Preserving

These settings only affect the timing and source of package installations, not functionality. Any package that has been published for more than 7 days will install normally. The project's existing dependencies (already in the lockfile) are unaffected because they were published long ago. Only new updates are subject to the quarantine.

Prevention & Best Practices

1. Always Configure Supply Chain Security Settings

For any project using pnpm v10.16.0+, include these settings in your pnpm-workspace.yaml:

minimumReleaseAge: 10080    # 7-day quarantine (minutes)
trustPolicy: no-downgrade   # Prevent security downgrades
blockExoticSubdeps: true    # Block non-registry transitive deps

2. Use Static Analysis on Configuration Files

Security scanners like Semgrep can detect missing security settings in package manager configurations. Include rules like package_managers.pnpm.pnpm-missing-minimum-release-age in your CI pipeline.

3. Layer Your Defenses

Supply chain security requires defense-in-depth:
- Lockfiles prevent unexpected changes during pnpm install
- minimumReleaseAge protects during intentional updates
- onlyBuiltDependencies limits which packages can run scripts
- trustPolicy prevents security regression
- Code review catches suspicious dependency changes

4. Monitor for Supply Chain Advisories

Subscribe to npm security advisories and use tools like pnpm audit regularly. The 7-day quarantine gives time for advisories to be published before you're affected.

5. Consider Stricter Values for High-Security Projects

For critical infrastructure, consider minimumReleaseAge: 20160 (14 days) or even longer. The tradeoff is slower access to new features vs. stronger protection against zero-day supply chain attacks.

Key Takeaways

  • The site-astro/pnpm-workspace.yaml file had zero supply chain quarantine protection — any freshly published malicious package could be installed immediately during updates
  • minimumReleaseAge: 10080 provides a 7-day safety net that catches the majority of supply chain attacks, which are typically detected within hours to days
  • trustPolicy: no-downgrade prevents a subtle attack vector where security settings in the lockfile are weakened through seemingly innocent PRs or CI modifications
  • Supply chain hardening in pnpm is a 3-line change that provides significant protection with zero impact on existing functionality
  • Configuration-level security settings are often overlooked — the onlyBuiltDependencies list showed security awareness, but the newer pnpm hardening features hadn't been adopted yet

How Orbis AppSec Detected This

  • Source: npm registry — newly published package versions available for installation without age verification
  • Sink: pnpm-workspace.yaml at the root configuration level in site-astro/, where dependency resolution policies are defined
  • Missing control: No minimumReleaseAge setting to enforce a quarantine period, no trustPolicy to prevent security downgrades, and no blockExoticSubdeps to restrict transitive dependency sources
  • CWE: CWE-829 (Inclusion of Functionality from Untrusted Control Sphere)
  • Fix: Added minimumReleaseAge: 10080, trustPolicy: no-downgrade, and blockExoticSubdeps: true to site-astro/pnpm-workspace.yaml

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 attacks remain one of the most dangerous threats to modern software projects. The site-astro project's pnpm-workspace.yaml was missing critical hardening settings that pnpm provides specifically to combat these attacks. By adding minimumReleaseAge: 10080, trustPolicy: no-downgrade, and blockExoticSubdeps: true, the project now has a 7-day quarantine for new packages, protection against security setting downgrades, and blocking of exotic transitive dependencies.

If you're using pnpm v10.16.0 or later, audit your pnpm-workspace.yaml files today. These three lines of configuration provide meaningful protection against an entire class of supply chain attacks — at zero cost to your development workflow.

References

Frequently Asked Questions

What is pnpm-missing-minimum-release-age?

It's a supply chain security misconfiguration where pnpm's workspace settings don't enforce a waiting period before installing newly published package versions, allowing potentially malicious packages to be installed immediately after publication.

How do you prevent missing minimum release age in pnpm?

Add `minimumReleaseAge: 10080` to your `pnpm-workspace.yaml` file (available since pnpm v10.16.0), which enforces a 7-day quarantine period before new package versions can be installed.

What CWE is pnpm-missing-minimum-release-age?

CWE-829: Inclusion of Functionality from Untrusted Control Sphere, as the application includes code from npm packages without verifying they've been vetted by the community over time.

Is using a lockfile enough to prevent supply chain attacks in pnpm?

No. While lockfiles prevent unexpected updates during `pnpm install`, they don't protect during intentional updates via `pnpm update`. The `minimumReleaseAge` setting provides defense-in-depth by ensuring even intentional updates only pull packages that have existed long enough to be community-vetted.

Can static analysis detect missing minimum release age?

Yes. Tools like Semgrep can scan `pnpm-workspace.yaml` files for missing security settings including `minimumReleaseAge`, `trustPolicy`, and `blockExoticSubdeps` using rules like `package_managers.pnpm.pnpm-missing-minimum-release-age.pnpm-minimum-release-age`.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #5

Related Articles

medium

How GitHub Actions Mutable Action Tags Enable Supply-Chain Attacks and How to Fix Them

A GitHub Actions workflow was using `actions/checkout@v1`, a mutable tag reference that could be silently repointed by the action owner to inject malicious code. This supply-chain vulnerability was fixed by pinning the action to a specific commit SHA (`11bd71901bbe5b1630ceea73d27597364c9af683`), ensuring the workflow always executes verified, immutable code.

high

How Path Traversal and Security Policy Bypass Happens in Node.js Dependencies and How to Fix It

A high-severity vulnerability in the fast-uri package (CVE-2026-6321) allowed attackers to bypass security policies through improper Unicode hostname canonicalization and path traversal. This issue affected the @apralabs/apra-fleet project through its dependency tree, and was resolved by upgrading fast-uri from version 3.1.0 to 4.1.2 using npm overrides.

high

How Arbitrary HTTP Header Injection via Prototype Pollution happens in JavaScript and how to fix it

A high-severity vulnerability (CVE-2026-42035) in axios version 1.13.5 allowed attackers to inject arbitrary HTTP headers through prototype pollution. The fix upgrades axios to version 1.18.0 in the frontend's dependency tree, which includes proper prototype chain validation when constructing HTTP request headers. This prevents attackers from manipulating outgoing requests to perform SSRF, session hijacking, or cache poisoning attacks.

high

How Shell Injection in GitHub Actions happens in YAML workflows and how to fix it

A high-severity shell injection vulnerability was discovered in `.forgejo/workflows/docker.yml` where `${{github.ref}}` and `${{github.ref_name}}` were directly interpolated into a bash `run:` step. An attacker could craft malicious git reference names to inject arbitrary commands into the CI runner, potentially stealing secrets and source code. The fix moves these values into intermediate environment variables, preventing command injection.

high

How XML Node Injection happens in JavaScript XML parsing and how to fix it

CVE-2026-41672 is a high-severity XML node injection vulnerability in the `@xmldom/xmldom` package, caused by insufficient validation during comment serialization that allows attackers to inject arbitrary XML nodes into a document. The fix upgrades `@xmldom/xmldom` from version 0.8.12 to 0.8.13 (and 0.9.x to 0.9.10), closing the injection path by tightening how untrusted comment content is handled before it reaches the serializer.

high

How Unauthenticated Denial of Service happens in React Router and how to fix it

CVE-2026-55685 is a high-severity Denial of Service vulnerability in React Router's `@remix-run/server-runtime` that allows unauthenticated attackers to exhaust server resources by sending crafted requests to the manifest endpoint. The fix upgrades `react-router` from version 7.17.0 to 7.18.0, which tightens handling of untrusted input in route matching logic. Developers using any React Router 7.x application with server-side rendering should apply this patch immediately.