Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
📦
📦 npm
Not in CISA KEV
HIGH severity

pnpm: Hoisted install imports lockfile alias outside node_modulesGHSA-fr4h-3cph-29xv

HIGH

GHSA-fr4h-3cph-29xv is a high-severity (CVSS 7.1) Path Traversal vulnerability in pnpm. A fix is available for pnpm — see the affected versions and patch details below.

Also known asCVE-2026-59196
Published
Updated
Affected
2 pkgs
Patched
2 / 2
Exploits
None indexed
Exploitation data as of Oct 13, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

No confirmed exploitation observed yet

  • CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.

Exploitation and automatability from CISA’s SSVC triage for GHSA-fr4h-3cph-29xv.

EPSS Exploitation Probability

via FIRST.org ↗
0.4%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs33th percentile — riskier than 33% of all scored CVEsHighest risk
0.00%0.30%0.60%0.90%0.3%0.4%0.4%0.4%Aug 26Oct 26Oct 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

GHSA-fr4h-3cph-29xv by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.

Where this sits among everything scored

Of 386,684 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.

Real-World Exposure

2 pkgs affected

How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.

406other npm packages depend on this — each one inherits the vulnerability until it's patched upstream
pnpmnpm
223.2Mdownloads / week

Description

Summary

The hoisted dependency alias issue tracked as GHSA-fr4h-3cph-29xv / CAND-PNPM-059 has been addressed in both pnpm and pacquet.

A crafted lockfile alias could be joined directly under a hoisted node_modules directory. Traversal aliases could escape that directory, while reserved aliases such as .bin or .pnpm could overwrite pnpm-owned layout. This patch validates package-name semantics and path containment before graph insertion or filesystem work.

Security boundary

  • The TypeScript hoisted graph uses the shared safe join helper at the actual dep.name sink.
  • The helper rejects traversal, absolute, platform-specific, and reserved package names.
  • Pacquet validates the hoister's dep.0.name before adding the graph node or recursing.
  • Both implementations return ERR_PNPM_INVALID_DEPENDENCY_NAME.
  • Pacquet uses the same dependency-name containment rule at its hoisted graph sink as it uses for direct dependency aliases.

Exploit replay

Before the patch, a traversal alias in a hoisted lockfile imported package files outside the intended install root. With this patch, both pnpm and pacquet reject the alias before graph insertion or filesystem work, and the escaped file is not created.

Files changed

  • fs/symlink-dependency/src/safeJoinModulesDir.ts provides the TypeScript containment helper.
  • installing/deps-restorer/src/lockfileToHoistedDepGraph.ts validates the parsed dependency name at the hoisted graph sink.
  • pacquet/crates/package-manager/src/{hoisted_dep_graph.rs,safe_join_modules_dir.rs} mirrors that boundary in Rust.
  • TypeScript and Rust tests cover traversal, reserved aliases, and valid scoped names.

Commands run

$ pnpm --filter @pnpm/fs.symlink-dependency test
PASS: 24 tests
$ pnpm --filter @pnpm/installing.deps-restorer test test/index.ts
PASS: exploit regression and positive install control
$ cargo test --locked -p pacquet-package-manager --lib
PASS: 426 tests
$ cargo fmt --all -- --check
PASS

Validation

  • TypeScript symlink helper: 24 passed.
  • TypeScript exploit regression: 1 passed.
  • TypeScript positive hoisted-install control: 1 passed.
  • Targeted strict TypeScript compiles: passed.
  • Targeted ESLint: zero errors.
  • Pacquet helper tests: 3 passed.
  • Full pacquet package-manager library suite: 426 passed.
  • cargo fmt, parsed two-document lockfile validation, and git diff --check: passed.

Patch

Ready-for-review private PR: https://github.com/pnpm/pnpm-ghsa-fr4h-3cph-29xv/pull/1

GitHub reports the branch as mergeable and has requested review from zkochan. GitHub intentionally does not run status checks on temporary private-fork PRs; the commands and outcomes above are the recorded local validation: https://docs.github.com/code-security/security-advisories/collaborating-in-a-temporary-private-fork-to-resolve-a-security-vulnerability

Compatibility

Valid unscoped and scoped package aliases continue to work. The changeset covers @pnpm/fs.symlink-dependency, @pnpm/installing.deps-restorer, and pnpm; pacquet is updated in the same commit for CLI parity.


Written by an agent (Codex, GPT-5).

Affected Packages

2 total 2 fixed
EcosystemPackageVulnerable rangeFix
📦npmpnpmall versions10.34.4npm install pnpm@10.34.4
📦npmpnpm≥ 11.0.0&&< 11.7.011.7.0npm install pnpm@11.7.0

Affected Products

1 product · 2 configurations
Application
pnpmpnpm
≥ 11.0.0 && < 11.7.0
range

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for pnpm, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update pnpm to 10.34.4 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-fr4h-3cph-29xv is resolved across your whole dependency graph.

  3. Workarounds

    Resolve every user-supplied path to its canonical form and reject anything that escapes the intended directory, and run the component under an account that has no read or write access outside the directory it legitimately serves.

Fixing This On Your OS

If you run this on a Linux distribution, patch through your package manager against the distro's own security advisory below — it tracks the exact backported fix for your release, which can ship on a different timeline (and sometimes a different severity) than the upstream project.

Red HatImportant

This Important vulnerability in pnpm, a package manager, allows a remote attacker to achieve arbitrary file write by manipulating the package installation process with a specially crafted lockfile alias. This could lead to path traversal, enabling the attacker to write files outside the designated installation…

Workaround published by Red Hat
Mitigation for this issue is either not available or the currently available options do not meet the Red Hat Product Security criteria comprising ease of use and deployment, applicability to widespread installation base, or stability.
Source: Red Hat security advisory for GHSA-fr4h-3cph-29xv (CC BY 4.0)

Frequently Asked Questions

## Summary The hoisted dependency alias issue tracked as GHSA-fr4h-3cph-29xv / CAND-PNPM-059 has been addressed in both pnpm and pacquet. A crafted lockfile alias could be joined directly under a hoisted `node_modules` directory. Traversal aliases could escape that directory, while reserved aliases such as `.bin` or `.pnpm` could overwrite pnpm-owned layout. This patch validates package-name semantics and path containment before graph insertion or filesystem work. ## Security boundary - The TypeScript hoisted graph uses the shared safe join helper at the actual `dep.name` sink. - The helpe
O3 Security · Impact-Aware SCA

Is GHSA-fr4h-3cph-29xv in your dependencies?

Find it across npm, including transitive dependencies.

pnpm: Hoisted install imports lockfile alias outside…