Backports three merged security fixes from main to release/10:
- Contain hoisted dependency aliases so a crafted lockfile alias cannot
escape node_modules or overwrite pnpm-owned layout. The hoisted graph
builder now validates each alias at the safeJoinModulesDir sink.
(GHSA-fr4h-3cph-29xv, #12343)
- Contain pnpm patch-remove deletions to the configured patches
directory. (#12341)
- Reject path-traversal config dependency names and versions from
pnpm-workspace.yaml before they are used to build filesystem paths.
(GHSA-qrv3-253h-g69c, #12470)
Written by an agent (Claude Code, claude-opus-4-8).
* fix(patching/apply-patch): reject patch paths that escape the patched directory
A malicious .patch file with `diff --git a/../../X` headers could otherwise
write, delete, or rename files outside the patched package as the user
running `pnpm install`.
* refactor(patching/apply-patch): narrow caught errors via util.types.isNativeError
Drops the `any`-typed catch + eslint-disable in favor of the cross-realm-safe
narrowing pattern documented in CLAUDE.md.
* refactor(patching/apply-patch): replace error helper with PatchPathEscapesError class
* chore(patching/apply-patch): reword comment to satisfy cspell
Git on Windows (Git for Windows / MSYS2) understands Unix-style
'/dev/null' but cannot access the native Windows null device '\\.\nul'
as a file path, causing "fatal: unable to access '\\.\nul'" errors.
This is a manual backport of the fix from #10757 on main.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(patch): prevent git config path errors in patch-commit
Replace HOME='' with GIT_CONFIG_GLOBAL to bypass user config
without breaking home directory resolution in restricted environments.
Fixes#6537
* fix(patch): prevent git config path errors in patch-commit
Use GIT_CONFIG_NOSYSTEM and GIT_CONFIG_GLOBAL to bypass git config
without breaking HOME path resolution in restricted environments.
Fixes#6537
Add `--no-color` to pnpm's invocation of `git diff` within the patch-commit
command. Ensures that the .diff files are valid when operating inside of
a git repository that has a local config that includes `diff.color=always`