Summary
pacquet, the Rust package-manager component used by pnpm, may trust dependency alias and package names from attacker-controlled lockfiles when constructing installation paths. A user who installs such a project with lockfile-trusting behavior enabled could cause symlinks, directories, binaries, or virtual-store entries to be created outside the intended project and node_modules boundaries.
Affected context
The vulnerability occurs during pnpm installations handled by pacquet when dependency names or aliases from a lockfile are used directly in filesystem joins. Risk is higher when a project uses an attacker-supplied lockfile and installation proceeds with trust-lockfile or frozen-lockfile behavior, allowing those values to influence dependency links, bin destinations, hoisted entries, or virtual-store paths.
Exploit preconditions
- Attack surface: Local package installation and filesystem materialization
- Required access: Ability to supply or influence the project's lockfile, plus a victim who installs the project
- Trigger point: Creation of dependency links, package links, bin destinations, hoisted entries, or virtual-store slots
- Why exploitation is possible: Dependency alias and name paths are accepted without sufficient containment validation before being joined with trusted installation directories
Why this happens
The underlying bug is path traversal caused by treating lockfile-derived dependency names and aliases as safe filesystem path components. Relative traversal segments, absolute paths, platform-specific path forms, or reserved names can escape the intended installation root when passed through filesystem joins without canonical containment checks. This maps to CWE-22: Improper Limitation of a Pathname to a Restricted Directory, because attacker-influenced path values can direct filesystem operations outside their permitted boundary.
Potential impact
- Files or directories could be created outside the intended project directory
- Symlinks could redirect package or executable references to unintended locations
- Existing files may be exposed to modification or replacement, depending on permissions
- Package installation integrity could be undermined
- Local code execution or broader compromise could occur if sensitive executable paths are affected
General mitigation guidance
Mitigation generally focuses on treating lockfile-derived names as untrusted path components and enforcing destination containment before any filesystem operation.
Common defensive patterns include:
- Validate dependency names, aliases, and virtual-store slots against a strict component-level schema
- Use a shared safe-join helper that rejects traversal, absolute, platform-specific, and reserved path forms
- Resolve or normalize candidate destinations and verify they remain within the intended root
- Apply validation before creating links, directories, binaries, or hoisted entries
- Minimize trust in externally supplied lockfiles and apply integrity or provenance checks
- Run package installation with least-privilege filesystem permissions and isolated workspaces
How teams detect issues like this
Organizations can look for this class of issue through:
- Static analysis of filesystem joins involving lockfile, manifest, or archive-derived values
- Code review signals such as direct concatenation of untrusted names into installation paths
- Tests covering relative traversal, absolute paths, alternate separators, reserved names, and symlink targets
- Runtime auditing of package-manager filesystem writes outside approved project and node_modules roots
- Policy checks that require canonical containment validation before filesystem materialization
- Automated security review tools that flag path construction from untrusted package metadata

