fix(arborist): block symlink escape in patch applier #10129

Open
rootvector2 opened 1:40am on October 15, 2026 wants to merge 25 Ξ” into npm/cli latest from
block-patch-applier-symlink-escape
Diff Delta:
25
About 16 Diff Delta/hour
Classified as:  Bug Fix

rootvector2's Description of Work

applyPatchToDir in @npmcli/arborist applies a registered patchedDependencies patch to a package that was just extracted from a registry tarball, and containedTarget is meant to keep every write and delete inside that package directory. The check is purely lexical (reject .. and absolute paths), so a publisher who ships a tarball with a symlink such as evil -> /outside at a directory the patch touches gets past it: the diff path evil/pwned.js looks contained, but the following writeFile/rm follows the symlink and lands outside the package during npm install/npm ci. This reworks the guard to refuse a symlink at the target and to require the real path of the deepest existing ancestor to stay inside the real package directory, which is the only layer that sees the extracted tree.

Added regression tests for the write and delete cases; both escape on the current tree and are blocked with the fix.

2 total changed files
Loading changes...
You’ve reached the end
The diff well is dry.