Repository navigation
fix(stage): sanitize the download filename from staged manifest fields - #10070
Open
ManoharPaturi wants to merge 1 commit into
Open
ManoharPaturi wants to merge 1 commit into
ManoharPaturi wants to merge 1 commit into
Conversation
The name and version used to build the downloaded tarball filename come from the staged tarball's own package.json, so they are registry controlled. Only the first slash was stripped from the name and the version was left untouched, so a crafted manifest could push path separators into the filename and write the tarball outside the current working directory. Sanitize the full filename the same way libnpmpack does for the same manifest fields, stripping every slash and backslash, so neither field can contribute path separators.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
npm stage download <stage-id>builds the output filename from the staged tarball's manifest:The name and version are read out of the tarball's own package.json (via
#readManifestFromTarball), so they are registry controlled. The sanitization only removed the first slash of the name and left the version untouched, so a crafted manifest could push path separators into the filename. With a version such as../../../outside,resolve(process.cwd(), filename)walks out of the working directory and the tarball is written to an arbitrary location, for example:This is the same class of defect fixed for the linked install strategy store key in #9758, where an untrusted package.json version became a path segment.
Solution
Build the filename from the raw name and version and strip every slash and backslash, exactly like
libnpmpackalready does for the same manifest fields (workspaces/libnpmpack/lib/index.js). With no separators surviving, neither field can move the destination outside the working directory.Test Evidence
Added a test in
test/lib/commands/stage/download.jsthat stages a tarball whose manifest carries a traversal version and asserts the file is written inside the cwd and that no file escapes it. The test fails on the previous code withtarball does not escape the cwdand passes with this change. Full file is green:npx tap test/lib/commands/stage/download.js.References
workspaces/libnpmpack/lib/index.js