GHSA-2rx9-3g3h-c2jv: Path Traversal

Published Sep 1, 2026
·
Updated

Summary

A crafted lockfile alias could reach several install-time filesystem joins. With --trust-lockfile or a frozen lockfile, traversal segments could create links outside the intended project or nodemodules boundary. This patch validates dependency names and every virtual-store slot before creating directories, links, bins, or hoisted entries.

Security boundary

- A shared safe-join helper rejects traversal, absolute, platform-specific, and reserved dependency names before filesystem materialization. - Direct and transitive dependency links, package links, bin destinations, and public/private hoist destinations use the same containment rule. - Global virtual-store slots validate the complete slot path, including version-derived components, before directory creation. - Snapshot slots and package names are checked before store initialization and before the current-lockfile fast path, closing the warm-install bypass. - Rejections preserve ERRPNPMINVALIDDEPENDENCYNAME.

Exploit replay

Before the patch, pacquet install --frozen-lockfile --trust-lockfile accepted a ../../escaped-link dependency key and created a symlink outside the project. With this patch, the same lockfile is rejected before materialization and no outside link is created.

Files changed

- pacquet/crates/package-manager/src/safejoinmodulesdir.rs defines the shared containment rule. - Install, symlink, bin, hoist, virtual-store, and frozen-lockfile paths call that helper before filesystem materialization. - The corresponding tests.rs files cover every sink, including warm installs and global virtual-store slots.

Commands run

text $ cargo test --locked -p pacquet-package-manager --lib PASS: 434 tests $ cargo clippy --locked -p pacquet-package-manager --all-targets -- --deny warnings PASS $ cargo fmt --all -- --check PASS

Validation

- Full pacquet package-manager suite: 434 passed. - Focused regressions cover direct and transitive aliases, bins, hoists, package names, global virtual-store version traversal, and a poisoned prior-install slot. - cargo clippy -p pacquet-package-manager --all-targets -- -D warnings: passed. - cargo fmt --all -- --check and git diff --check: passed.

Compatibility

Valid unscoped and scoped dependency aliases continue to work. The reproduced escape was specific to pacquet, so this branch does not change the TypeScript CLI or the lockfile format.

--- Written by an agent (Codex, GPT-5).

Affected Software

1 affected componentFixes available
npm/pnpm>=12.0.0-alpha.0<12.0.0-alpha.5
12.0.0-alpha.5

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade npm/pnpm to a version that resolves this vulnerability.

    Fixed in 12.0.0-alpha.5

Event History

Sep 1, 2026
Advisory Published
via GitHub·06:59 PM
Data Sourced
via GitHub·06:59 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

Which installation workflows are exposed?

Installations using --trust-lockfile or a frozen lockfile are affected when the lockfile contains crafted dependency aliases or virtual-store slot paths. The issue can affect direct and transitive dependency links, package links, bin destinations, hoisted entries, and global virtual-store slots.

2

What does an attacker need to exploit this?

An attacker needs a crafted lockfile containing traversal-style dependency keys or slot components, such as ../../escaped-link. Exploitation is triggered when the affected installation workflow materializes filesystem directories or links from that lockfile.

3

What can be done if the patch cannot be deployed immediately?

Do not use --trust-lockfile or frozen-lockfile installation modes with lockfiles that are not trusted and reviewed. Treat lockfiles as security-sensitive input because crafted entries can cause links to be created outside the intended project or node_modules boundary.

4

How can a patched installation indicate that it blocked malicious input?

Rejected dependency names preserve the ERR_PNPM_INVALID_DEPENDENCY_NAME error. The validation applies before store initialization, including the current-lockfile fast path, so warm installs should also reject invalid names or slot paths.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203