Executive brief
pnpm is a package manager that installs JavaScript dependencies. A crafted lockfile (pnpm-lock.yaml) can cause pnpm to write package files to arbitrary locations on a user's filesystem instead of the intended dependency folder when running `pnpm install`. An attacker who commits a malicious lockfile to a repository can compromise any developer or system that installs dependencies, leading to file overwrites in sensitive locations like git hooks (enabling code execution) or binary directories.
Technical details
This is a path traversal vulnerability (CWE-22) in pnpm's lockfile parsing and package installation flow. The vulnerable code extracts package names from lockfile `packages` keys using `dp.parse(depPath).name` without validation; a depPath like `../../../tmp/pwned@1.0.0` yields a name of `../../../tmp/pwned`. This unvalidated name is then passed to `path.join(modules, pkgName)` in `lockfileToDepGraph.ts:233`, allowing the resolved path to escape the virtual store and point to arbitrary locations (e.g., `/tmp/pwned`). The package content is subsequently written to this traversed path via `storeController.importPackage()`. Attack requires the victim to run `pnpm install` on a repository containing a crafted lockfile—user interaction is required but typical for development workflows. No authentication is needed. The same flaw affects the PnP linker configuration and can escalate to RCE if `dangerouslyAllowAllBuilds: true` is set, allowing postinstall scripts to execute at the traversed path. Patches are available in versions 10.34.5 and 11.11.0.
Affected products
- pnpm pnpm < 10.34.5, >= 11.0.0 < 11.11.0
Timeline
- 2026-09-02: disclosed: GitHub Security Advisory GHSA-c59q-g84q-2gj5 published
- 2026: patched: Fixed in pnpm 10.34.5 and 11.11.0