chore(deps): update pnpm.catalog.unrelated pnpm to v11 [security] - autoclosed#25
Closed
renovate[bot] wants to merge 1 commit into
Closed
chore(deps): update pnpm.catalog.unrelated pnpm to v11 [security] - autoclosed#25renovate[bot] wants to merge 1 commit into
renovate[bot] wants to merge 1 commit into
Conversation
❌ Deploy Preview for stacks-everything failed. Why did it fail? →
|
renovate
Bot
force-pushed
the
renovate/npm-pnpm-vulnerability
branch
2 times, most recently
from
January 28, 2026 19:44
724dc00 to
106c79d
Compare
renovate
Bot
force-pushed
the
renovate/npm-pnpm-vulnerability
branch
from
March 6, 2026 15:48
106c79d to
6e82d6d
Compare
renovate
Bot
force-pushed
the
renovate/npm-pnpm-vulnerability
branch
2 times, most recently
from
March 30, 2026 19:05
6e82d6d to
e5c93c7
Compare
renovate
Bot
force-pushed
the
renovate/npm-pnpm-vulnerability
branch
2 times, most recently
from
April 27, 2026 20:38
e5c93c7 to
9c4a45e
Compare
renovate
Bot
force-pushed
the
renovate/npm-pnpm-vulnerability
branch
2 times, most recently
from
May 18, 2026 13:40
689bd30 to
5ce40e0
Compare
renovate
Bot
force-pushed
the
renovate/npm-pnpm-vulnerability
branch
2 times, most recently
from
June 2, 2026 00:01
357531f to
bf9a545
Compare
renovate
Bot
force-pushed
the
renovate/npm-pnpm-vulnerability
branch
from
June 11, 2026 22:07
bf9a545 to
f2876d8
Compare
renovate
Bot
force-pushed
the
renovate/npm-pnpm-vulnerability
branch
from
June 30, 2026 17:50
f2876d8 to
0429147
Compare
renovate
Bot
force-pushed
the
renovate/npm-pnpm-vulnerability
branch
from
July 12, 2026 14:12
0429147 to
d497bdb
Compare
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.
This PR contains the following updates:
^10.12.1→^11.0.010.12.1→11.5.3pnpm vulnerable to Command Injection via environment variable substitution
CVE-2025-69262 / GHSA-2phv-j68v-wwqx
More information
Details
Summary
A command injection vulnerability exists in pnpm when using environment variable substitution in
.npmrcconfiguration files withtokenHelpersettings. An attacker who can control environment variables during pnpm operations could achieve remote code execution (RCE) in build environments.Affected Components
@pnpm/config.env-replaceandloadTokenfunctionalitypnpm/network/auth-header/src/getAuthHeadersFromConfig.ts-loadToken()functionpnpm/config/config/src/readLocalConfig.ts-.npmrcenvironment variable substitutionTechnical Details
Vulnerability Chain
Environment Variable Substitution
.npmrcsupports${VAR}syntaxreadLocalConfig()loadToken Execution
spawnSync(helperPath, { shell: true })Attack Flow
Code Evidence
pnpm/config/config/src/readLocalConfig.ts:17-18pnpm/network/auth-header/src/getAuthHeadersFromConfig.ts:60-71Proof of Concept
Prerequisites
PoC Steps
PoC Results
Impact
Severity
Affected Environments
High Risk:
Low Risk:
Attack Scenarios
Scenario 1: CI/CD Supply Chain
Scenario 2: Docker Build
Scenario 3: Kubernetes
Mitigation
Temporary Workarounds
Disable tokenHelper:
Use direct tokens:
//registry.npmjs.org/:_authToken=YOUR_TOKENAudit environment variables:
Recommended Fixes
shell: truefrom loadTokenDisclosure
References
@pnpm/config.env-replace@^3.0.2Credit
Reported by: Jiyong Yang
Contact: sy2n0@naver.com
Severity
CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:C/C:H/I:H/A:HReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
pnpm v10+ Bypass "Dependency lifecycle scripts execution disabled by default"
CVE-2025-69264 / GHSA-379q-355j-w6rj
More information
Details
pnpm v10+ Git Dependency Script Execution Bypass
Summary
A security bypass vulnerability in pnpm v10+ allows git-hosted dependencies to execute arbitrary code during
pnpm install, circumventing the v10 security feature "Dependency lifecycle scripts execution disabled by default". While pnpm v10 blockspostinstallscripts via theonlyBuiltDependenciesmechanism, git dependencies can still executeprepare,prepublish, andprepackscripts during the fetch phase, enabling remote code execution without user consent or approval.Details
pnpm v10 introduced a security feature to disable dependency lifecycle scripts by default (PR #8897). This is implemented by setting
onlyBuiltDependencies = []when no build policy is configured:File:
pkg-manager/core/src/install/extendInstallOptions.ts(lines 290-291)This creates an allowlist that blocks all packages from running scripts during the BUILD phase in
exec/build-modules/src/index.ts.However, git-hosted dependencies are processed differently. During the FETCH phase, git packages are prepared using
preparePackage():File:
exec/prepare-package/src/index.ts(lines 28-57)The
ignoreScriptsoption defaults tofalseand is completely separate fromonlyBuiltDependencies. TheonlyBuiltDependenciesallowlist is never consulted during the fetch phase.Affected scripts that execute during fetch:
prepareprepublishprepackAttack vectors:
git+https://github.com/attacker/malicious.gitgithub:attacker/maliciousgitlab:attacker/maliciousbitbucket:attacker/maliciousgit+ssh://git@github.com/attacker/malicious.gitgit+file:///path/to/local/repoPoC
Prerequisites:
Steps to reproduce:
Extract the attached poc.zip
Run the PoC script:
cd poc chmod +x run-poc.sh ./run-poc.shVerify the marker file was created by the malicious script:
Manual reproduction:
Create a malicious package with a
preparescript:{ "name": "malicious-pkg", "version": "1.0.0", "scripts": { "prepare": "node -e \"require('fs').writeFileSync('/tmp/pwned.txt', 'RCE!')\"" } }Initialize it as a git repo and commit the files
Create a victim project that depends on it (just have to make sure it actually git clones and not just downloads a tarball):
{ "dependencies": { "malicious-pkg": "git+file:///path/to/malicious-pkg" } }Run
pnpm install- the prepare script executes without any warning or approval promptImpact
Severity: High
Who is impacted:
Attack scenarios:
pnpm installWhat an attacker can do:
Why this bypasses security expectations:
onlyBuiltDependenciesconfiguration does not affect git dependenciesSeverity
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:HReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
pnpm Has Lockfile Integrity Bypass that Allows Remote Dynamic Dependencies
CVE-2025-69263 / GHSA-7vhp-vf5g-r2fw
More information
Details
Summary
HTTP tarball dependencies (and git-hosted tarballs) are stored in the lockfile without integrity hashes. This allows the remote server to serve different content on each install, even when a lockfile is committed.
Details
When a package depends on an HTTP tarball URL, pnpm's tarball resolver returns only the URL without computing an integrity hash:
resolving/tarball-resolver/src/index.ts:The resulting lockfile entry has no integrity to verify:
Since there is no integrity hash, pnpm cannot detect when the server returns different content.
This affects:
"pkg": "https://example.com/pkg.tgz")"pkg": "github:user/repo")"pkg": "git+https://github.com/user/repo")npm registry packages are not affected as they include integrity hashes from the registry metadata.
PoC
See attached pnpm-bypass-integrity-poc.zip
The POC includes:
malicious-packagethat depends on the HTTP tarballvictimproject that depends onmalicious-packageTo run:
cd pnpm-bypass-integrity-poc ./run-poc.shThe output shows that each install (with
pnpm store prunebetween them) downloads different code despite having a committed lockfile.Impact
An attacker who publishes a package with an HTTP tarball dependency can serve different code to different users or CI/CD environments. This enables:
The attack requires the victim to install a package that has an HTTP/git tarball in its dependency tree. The victim's lockfile provides no protection.
Severity
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:HReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
pnpm has symlink traversal in file:/git dependencies
CVE-2026-24056 / GHSA-m733-5w8f-5ggw
More information
Details
Summary
When pnpm installs a
file:(directory) orgit:dependency, it follows symlinks and reads their target contents without constraining them to the package root. A malicious package containing a symlink to an absolute path (e.g.,/etc/passwd,~/.ssh/id_rsa) causes pnpm to copy that file's contents intonode_modules, leaking local data.Preconditions: Only affects
file:andgit:dependencies. Registry packages (npm) have symlinks stripped during publish and are NOT affected.Details
The vulnerability exists in
store/cafs/src/addFilesFromDir.ts. The code usesfs.statSync()andreadFileSync()which follow symlinks by default:There is no check that
absolutePathresolves to a location inside the package directory.PoC
Impact
~/.aws/credentials,~/.npmrc,~/.ssh/id_rsaSuggested Fix
Use
lstatSyncto detect symlinks and reject those pointing outside the package root instore/cafs/src/addFilesFromDir.ts.Severity
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:A/VC:H/VI:N/VA:N/SC:N/SI:N/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
pnpm scoped bin name Path Traversal allows arbitrary file creation outside node_modules/.bin
CVE-2026-23890 / GHSA-xpqm-wm3m-f34h
More information
Details
Summary
A path traversal vulnerability in pnpm's bin linking allows malicious npm packages to create executable shims or symlinks outside of
node_modules/.bin. Bin names starting with@bypass validation, and after scope normalization, path traversal sequences like../../remain intact.Details
The vulnerability exists in the bin name validation and normalization logic:
1. Validation Bypass (
pkg-manager/package-bins/src/index.ts)The filter allows any bin name starting with
@to pass through without validation:2. Incomplete Normalization (
pkg-manager/package-bins/src/index.ts)3. Exploitation (
pkg-manager/link-bins/src/index.ts:288)The normalized name is used directly in
path.join()without validation.PoC
{ "name": "malicious-pkg", "version": "1.0.0", "bin": { "@​scope/../../.npmrc": "./malicious.js" } }.npmrccreated in project root (outside node_modules/.bin).Impact
Verified on pnpm main @ commit 5a0ed1d45.
Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
pnpm has Windows-specific tarball Path Traversal
CVE-2026-23889 / GHSA-6x96-7vc8-cm3p
More information
Details
Summary
A path traversal vulnerability in pnpm's tarball extraction allows malicious packages to write files outside the package directory on Windows. The path normalization only checks for
./but not.\. On Windows, backslashes are directory separators, enabling path traversal.This vulnerability is Windows-only.
Details
1. Incomplete Path Normalization (
store/cafs/src/parseTarball.ts:107-110)A path like
foo\..\..\.npmrcdoes NOT contain./and bypasses this check.2. Platform-Dependent Behavior (
fs/indexed-pkg-importer/src/importIndexedDir.ts:97-98)PoC
package/foo\..\..\.npmrcpnpm install.npmrcwritten outside package directoryImpact
.npmrc, build configs, or other filesVerified on pnpm main @ commit 5a0ed1d45.
Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
pnpm has Path Traversal via arbitrary file permission modification
CVE-2026-24131 / GHSA-v253-rj99-jwpq
More information
Details
Summary
When pnpm processes a package's
directories.binfield, it usespath.join()without validating the result stays within the package root. A malicious npm package can specify"directories": {"bin": "../../../../tmp"}to escape the package directory, causing pnpm to chmod 755 files at arbitrary locations.Note: Only affects Unix/Linux/macOS. Windows is not affected (
fixBingated byEXECUTABLE_SHEBANG_SUPPORTED).Details
Vulnerable code in
pkg-manager/package-bins/src/index.ts:15-21:The
binfield IS protected withisSubdir()at line 53, butdirectories.binlacks this check.PoC
Impact
Suggested Fix
Add
isSubdirvalidation fordirectories.binpaths inpkg-manager/package-bins/src/index.ts, matching the existing validation incommandsFromBin():Severity
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:A/VC:H/VI:N/VA:N/SC:N/SI:N/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
pnpm: Binary ZIP extraction allows arbitrary file write via path traversal (Zip Slip)
CVE-2026-23888 / GHSA-6pfh-p556-v868
More information
Details
Summary
A path traversal vulnerability in pnpm's binary fetcher allows malicious packages to write files outside the intended extraction directory. The vulnerability has two attack vectors: (1) Malicious ZIP entries containing
../or absolute paths that escape the extraction root via AdmZip'sextractAllTo, and (2) TheBinaryResolution.prefixfield is concatenated into the extraction path without validation, allowing a crafted prefix like../../evilto redirect extracted files outsidetargetDir.Details
The vulnerability exists in the binary fetching and extraction logic:
1. Unvalidated ZIP Entry Extraction (
fetching/binary-fetcher/src/index.ts)AdmZip's
extractAllTodoes not validate entry paths for path traversal:A ZIP entry with path
../../../.npmrcwill be written outsidenodeDir.2. Unvalidated Prefix in BinaryResolution (
resolving/resolver-base/src/index.ts)The
basenamevariable comes fromBinaryResolution.prefixand is used directly in path construction:PoC
Attack Vector 1: ZIP Entry Path Traversal
Attack Vector 2: Prefix Traversal via malicious resolution:
{ "resolution": { "type": "binary", "url": "https://attacker.com/node.zip", "prefix": "../../PWNED" } }Impact
Verified on pnpm main @ commit
5a0ed1d45.Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
pnpm: Tarball hash of GitHub git dependencies is not stored in lockfile
CVE-2026-48995 / GHSA-hg3w-7f8c-63hp
More information
Details
Summary
A malicious
codeload.github.comserver can serve whatever tarball it wants and pnpm will install it regardless of the lockfile.Details
The lockfile does not store the hash of the dependencies from https://codeload.github.com
This means that if this server was compromised or a person's machine configuration was compromised, pnpm would download and install these dependencies.
PoC
> pnpm -v 10.28.2Given the following package.json:
{ "dependencies": { "add": "git://github.com/dsherret/npm-git-dep.git#b3eeb9b" } }This produces a lockfile like so:
Notice that there is no hash. The
b3eeb9bis not sufficient because I can configure my machine to resolve a compromised tarball from that url (I tested it out and pnpm just installs it).Impact
Anyone relying on github git dependencies.
Severity
CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:UReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
pnpm: Unsafe default behavior breaks integrity check
CVE-2026-50573 / GHSA-54hh-g5mx-jqcp
More information
Details
While it is unclear whether this should be classified as a vulnerability, it is being reported through this channel because the current behavior may represent an unsafe default.
Summary
pnpm installin non-frozen mode can accept new remote package content after detecting that the downloaded tarball does not match the integrity recorded inpnpm-lock.yaml.When a package is already locked with an
integrityvalue, and the registry later serves different metadata and tarball content for the same package name and version, pnpm initially reports an integrity mismatch. However, plainpnpm installthen performs a resolution repair, accepts the registry's new integrity, updates the lockfile, installs the new content, and exits successfully.This means the lockfile integrity check does not act as a hard stop by default.
Reproduction Scenario
example-package@1.0.0with tarball contentv1.pnpm-lock.yamlcontains thev1integrity:example-package@1.0.0to contentv2.Observed Behavior
pnpm detects the checksum mismatch:
However, the install still succeeds:
The lockfile is then rewritten to trust the new remote integrity:
Expected Behavior
If a downloaded tarball does not match the integrity recorded in
pnpm-lock.yaml, the install should fail by default.The lockfile integrity should be treated as authoritative unless the user explicitly requests lockfile repair or dependency update behavior.
Security Impact
This behavior weakens the protection normally expected from a committed lockfile.
If a registry is compromised and an attacker overwrites the metadata and tarball for an existing package version, a new environment without the old pnpm store/cache may install the attacker's replacement package even though the project already has a lockfile with the original integrity.
Examples of affected new or clean environments include:
In this situation, pnpm first detects that the downloaded tarball does not match the integrity stored in
pnpm-lock.yaml. However, instead of failing by default, plainpnpm installperforms a resolution repair, trusts the current remote registry metadata, updates the lockfile to the new integrity, and installs the new registry content.In other words, when the lockfile and registry disagree, the default non-frozen behavior can end up trusting the remote registry over the content previously recorded in the lockfile.
This is especially relevant for:
The behavior is also surprising because the command reports an integrity error but still exits successfully after resolution repair.
This issue does not occur when
--frozen-lockfileis enabled. In frozen mode, the same integrity mismatch fails the install and does not install the changed package content.However, since the lockfile already records an integrity value, the integrity for the same package version should normally not change. If it does change, one likely explanation is that the server or registry has been compromised or is serving mutated package content. Under normal package publishing workflows, changed package content should be published as a new version instead of replacing an existing version.
For that reason, it may be safer for pnpm's default behavior to be closer to frozen mode for this specific case. At minimum, pnpm should not automatically repair the lockfile and trust the registry after an integrity mismatch. It should fail and let the user explicitly decide whether to discard the locked integrity, re-resolve the package from the remote registry, and update the lockfile.
Comparison
In the same scenario,
npm installwith an existingpackage-lock.jsonfails withEINTEGRITYand does not install the changed tarball.pnpm install --frozen-lockfilealso fails as expected:The issue is specific to the default non-frozen behavior of plain
pnpm installin non-CI environment.Severity
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
pnpm Has an Integrity Check Bypass via Missing Lockfile Integrity Field
CVE-2026-50021 / GHSA-q6j5-fjx5-2mc3
More information
Details
Summary
pnpm's tarball extraction worker skips integrity verification when the
integrityfield is absent from the lockfile resolution. If an attacker can both modifypnpm-lock.yamlto remove theintegrity:field and cause the referenced registry URL to serve altered package content,pnpm install --frozen-lockfilecan install the altered package without an integrity error. npm'snpm cienforces integrity by default; pnpm's behavior of silently skipping verification is a pnpm-specific fail-open gap.Vulnerability Details
The
addTarballToStorefunction inworker/src/start.ts(lines 189-204) checksif (integrity)before verifying the tarball hash. TheTarballResolutiontype declaresintegrityas optional (integrity?: string). When the lockfile omits theintegrityfield, the guard evaluates tofalse, skipping hash verification entirely. The worker then computes a new hash from the unverified content and stores it as legitimate.Proof of Concept
Impact
Supply chain compromise in environments where an attacker can both alter the lockfile and cause the referenced registry URL to serve altered package content. The
--frozen-lockfileflag does not fail closed when the integrity field is missing.Suggested Remediation
Require an
integrityfield for remote tarball resolutions. Change theif (integrity)guard to fail when integrity is absent for non-local packages. When--frozen-lockfileis active, reject lockfile entries that lack integrity for remote packages.Severity
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
pnpm: Git Fetch Argument Injection via Lockfile resolution.commit
CVE-2026-50014 / GHSA-p4xf-rf54-rj3x
More information
Details
Summary
pnpm passes the lockfile-controlled git
resolution.commitvalue togit fetchwithout a--separator or commit-format validation. For git dependencies fetched through the shallow-fetch path, a malicious lockfile can replace the expected 40-character commit hash with a Git option such as--upload-pack=<command>. For SSH and local transports,--upload-packcan execute the supplied command. HTTPS transports ignore--upload-pack, so the practical attack surface is primarily SSH or local git dependencies.Vulnerability Details
The vulnerable path is in
fetching/git-fetcher/src/index.ts. When a git dependency host is configured for shallow fetching, pnpm calls:Because
resolution.commitis appended before a--separator, Git can parse a commit value beginning with-as an option. The same file later passes the value togit checkoutwithout a separator:resolution.commitcomes from the lockfile and is typed as a plainstring; pnpm does not validate it as a 40-character hexadecimal commit before passing it to Git.Proof of Concept
The PoC uses a local
file://githost/...repository because the injection requires a local or SSH transport. HTTPS transport ignores--upload-pack.Impact
Code execution as the user running
pnpm install, under specific transport conditions. The attacker must modifypnpm-lock.yaml, and the affected dependency must use SSH or local git transport. HTTPS transport (the common case) is immune.Suggested Remediation
Add a
--separator before lockfile-controlled git revision values. Validateresolution.commitmatches/^[0-9a-f]{40}$/ibefore passing to Git.Severity
CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:H/I:H/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
pnpm: Transitive dependency alias path traversal allows project path override via symlink replacement
CVE-2026-50016 / GHSA-hwx4-2j3j-g496
More information
Details
Summary
pnpm allows a transitive dependency alias from registry package metadata to contain path traversal segments. During install, pnpm later uses that alias as a filesystem path when linking dependency nodes. As a result, a registry package can cause
pnpm install - ignore-scriptsto replace paths in the current project with symlinks to attacker-controlled dependency package directories..git/hooksis only one useful target. The same primitive can replace other project-local paths that are consumed by later tools, for example:.huskyor.githooksfor Git hook dispatchersscripts/,tools/,bin/, ortests/for project scripts and CI commands.github/actions/<name>for local GitHub Actions used later in the workflowdist/or other publish/build output directories beforepnpm packorpnpm publishnode_modules/.binor undeclarednode_modules/<name>paths used by latercommand or module resolution
Targets that are regular files can also be replaced with symlinks to a package directory, but those cases are usually denial of service. Directory targets are more useful because many developer tools execute or load files from those directories after installation.
This was reproduced with
pnpm@11.2.1.Impact
Users often run
pnpm install --ignore-scriptsexpecting that untrusted package code cannot execute during installation. This issue bypasses that expectation: the malicious package does not need a lifecycle script. Instead, it silently rewires project files or directories during install, and the payload runs when the user or CI later executes another normal command.Examples include
git commit,pnpm test,pnpm run build, a CI step that uses a local GitHub Action, orpnpm publishpackaging a replaceddist/directory. In this PoC, the victim installs a normal registry package, the transitive malicious package replaces.git/hooks, and the payload runs when the victim later executesgit commit.Root Cause
pnpm preserves dependency alias names from package metadata and later passes those aliases into dependency linking as path components. The alias is joined with the destination
node_modulesdirectory and passed to the symlink creation logic without rejecting..segments or checking that the normalized result stays inside the intendednode_modulesdirectory.Conceptually, a transitive alias like this:
{ "@​x/../../../../../.git/hooks": "npm:payload-hooks@1.0.0" }is eventually treated like:
The normalized destination escapes the dependency's
node_modulesdirectory and lands at the victim project's.git/hookspath. pnpm then creates a symlink at that escaped destination to the resolvedpayload-hookspackage directory.The dependency chain is:
The malicious transitive package metadata contains:
{ "@​x/../../../../../.git/hooks": "npm:payload-hooks@1.0.0" }Because this uses an
npm:registry alias, it does not rely on a transitivefile:orlink:dependency.Proof Of Concept
Run:
The script starts a local npm-compatible registry, writes a victim project
.npmrcthat points to that registry, installsnormal@1.0.0with--ignore-scripts, and then triggersgit commit.Requirements:
Expected output:
PWNEDis printed by the attacker-controlledpre-commithook from thepayload-hookspackage.Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:HReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
pnpm binds unscoped user-level npm auth credentials to a repository-selected registry
CVE-2026-50017 / GHSA-cjhr-43r9-cfmw
More information
Details
Summary
pnpm can send user-level unscoped npm authentication credentials to a registry chosen by a repository-local
.npmrcfile.In the reproduced case, the us