{"id":"CVE-2026-50014","aliases":["EUVD-2026-39490","GHSA-p4xf-rf54-rj3x","ROOT-APP-NPM-CVE-2026-50014"],"status":"published","title":"pnpm: Git Fetch Argument Injection via Lockfile resolution.commit","description":"pnpm is a package manager. Prior to 10.34.0 and 11.4.0, pnpm passes the lockfile-controlled git resolution.commit value to git fetch without 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=\u003ccommand\u003e. For SSH and local transports, --upload-pack can execute the supplied command. HTTPS transports ignore --upload-pack, so the practical attack surface is primarily SSH or local git dependencies. This vulnerability is fixed in 10.34.0 and 11.4.0.","severity":{"version":"3.1","score":6.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:H/I:H/A:N","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-11","score":0.00318,"percentile":0.25078,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-88"],"published":"2026-06-25T16:51:16Z","modified":"2026-11-03T22:13:26Z","fixes":[{"ecosystem":"npm","package":"pnpm","fixed_in":["10.34.0","11.4.0"],"sources":["ghsa","osv"]},{"ecosystem":"Root:npm","package":"@rootio/pnpm","fixed_in":["10.32.1-root.io.4"],"sources":["osv"]},{"ecosystem":"Root:npm","package":"pnpm","fixed_in":["10.32.1-aikido.4"],"sources":["osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"pnpm","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"10.34.0"}]}]},{"source":"ghsa","ecosystem":"npm","package":"pnpm","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.0.0"},{"fixed":"11.4.0"}]}]},{"source":"osv","ecosystem":"npm","package":"pnpm","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"10.34.0"}]}]},{"source":"osv","ecosystem":"npm","package":"pnpm","ranges":[{"type":"SEMVER","events":[{"introduced":"11.0.0"},{"fixed":"11.4.0"}]}]},{"source":"osv","ecosystem":"Root:npm","package":"@rootio/pnpm","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"10.32.1-root.io.4"}]}]},{"source":"osv","ecosystem":"Root:npm","package":"pnpm","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"10.32.1-aikido.4"}]}]}],"products":[{"vendor":"pnpm","product":"pnpm"}],"references":[{"url":"https://github.com/pnpm/pnpm/security/advisories/GHSA-p4xf-rf54-rj3x","tags":["x_refsource_CONFIRM","exploit","Exploit","Mitigation","Vendor Advisory","advisory","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-50014","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-p4xf-rf54-rj3x"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/50xxx/CVE-2026-50014.json","tags":["advisory"]},{"url":"https://github.com/pnpm/pnpm","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-50014","title":"pnpm: Git Fetch Argument Injection via Lockfile resolution.commit","description":"pnpm is a package manager. Prior to 10.34.0 and 11.4.0, pnpm passes the lockfile-controlled git resolution.commit value to git fetch without 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=\u003ccommand\u003e. For SSH and local transports, --upload-pack can execute the supplied command. HTTPS transports ignore --upload-pack, so the practical attack surface is primarily SSH or local git dependencies. This vulnerability is fixed in 10.34.0 and 11.4.0.","status":"published","published":"2026-06-25T16:51:16.652Z","modified":"2026-11-03T22:13:26.306Z","cvss":[{"version":"3.1","score":6.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:H/I:H/A:N","level":"medium","assessor":"cna"}],"cwes":["CWE-88"],"updated_at":"2026-11-03T23:33:09.822755Z"}],"euvd":[{"id":"EUVD-2026-39490","description":"pnpm is a package manager. Prior to 10.34.0 and 11.4.0, pnpm passes the lockfile-controlled git resolution.commit value to git fetch without 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=\u003ccommand\u003e. For SSH and local transports, --upload-pack can execute the supplied command. HTTPS transports ignore --upload-pack, so the practical attack surface is primarily SSH or local git dependencies. This vulnerability is fixed in 10.34.0 and 11.4.0.","status":"published","published":"2026-06-25T16:51:16Z","modified":"2026-11-03T22:13:26Z","cvss":[{"version":"3.1","score":6.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:H/I:H/A:N","level":"medium"}],"updated_at":"2026-11-03T23:01:34.013136Z"}],"ghsa":[{"id":"GHSA-p4xf-rf54-rj3x","title":"pnpm: Git Fetch Argument Injection via Lockfile resolution.commit","description":"## Summary\n\npnpm passes the lockfile-controlled git `resolution.commit` value to `git fetch` without 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=\u003ccommand\u003e`. For SSH and local transports, `--upload-pack` can execute the supplied command. HTTPS transports ignore `--upload-pack`, so the practical attack surface is primarily SSH or local git dependencies.\n\n## Vulnerability Details\n\nThe vulnerable path is in `fetching/git-fetcher/src/index.ts`. When a git dependency host is configured for shallow fetching, pnpm calls:\n\n```typescript\nawait execGit(['fetch', '--depth', '1', 'origin', resolution.commit], { cwd: tempLocation })\n```\n\nBecause `resolution.commit` is appended before a `--` separator, Git can parse a commit value beginning with `-` as an option. The same file later passes the value to `git checkout` without a separator:\n\n```typescript\nawait execGit(['checkout', resolution.commit], { cwd: tempLocation })\n```\n\n`resolution.commit` comes from the lockfile and is typed as a plain `string`; pnpm does not validate it as a 40-character hexadecimal commit before passing it to Git.\n\n## Proof of Concept\n\n```bash\nbash autofyn_audit/exploits/vuln11_git_upload_pack_rce/exploit.sh\n# Creates a local bare git repo and triggers the shallow-fetch path.\n# Replaces the lockfile commit hash with '--upload-pack=touch /tmp/vuln11_pwned'.\n# Result: PASS -- /tmp/vuln11_pwned created by injected touch command.\n```\n\nThe PoC uses a local `file://githost/...` repository because the injection requires a local or SSH transport. HTTPS transport ignores `--upload-pack`.\n\n## Impact\n\nCode execution as the user running `pnpm install`, under specific transport conditions. The attacker must modify `pnpm-lock.yaml`, and the affected dependency must use SSH or local git transport. HTTPS transport (the common case) is immune.\n\n## Suggested Remediation\n\nAdd a `--` separator before lockfile-controlled git revision values. Validate `resolution.commit` matches `/^[0-9a-f]{40}$/i` before passing to Git.\n\n---\n\n\u003e Discovered by [AutoFyn](https://github.com/SignalPilot-Labs/AutoFyn)\n\u003e Full audit report: [audit_report.md](https://github.com/tempcollab/pnpm/blob/main/autofyn_audit/audit_report.md)\n\u003e Exploit script: [exploit.sh](https://github.com/tempcollab/pnpm/blob/main/autofyn_audit/exploits/vuln11_git_upload_pack_rce/exploit.sh)","status":"published","published":"2026-06-26T22:53:21Z","modified":"2026-06-26T22:53:22Z","cvss":[{"version":"3.1","score":6.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:H/I:H/A:N","level":"medium"}],"cwes":["CWE-88"],"updated_at":"2026-11-02T14:40:34.713036Z"}],"nvd":[{"id":"CVE-2026-50014","description":"pnpm is a package manager. Prior to 10.34.0 and 11.4.0, pnpm passes the lockfile-controlled git resolution.commit value to git fetch without 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=\u003ccommand\u003e. For SSH and local transports, --upload-pack can execute the supplied command. HTTPS transports ignore --upload-pack, so the practical attack surface is primarily SSH or local git dependencies. This vulnerability is fixed in 10.34.0 and 11.4.0.","status":"published","published":"2026-06-25T18:16:39.043Z","modified":"2026-11-03T23:17:46.1Z","cvss":[{"version":"3.1","score":6.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:H/I:H/A:N","level":"medium","assessor":"secondary"},{"version":"3.1","score":7.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N","level":"high","assessor":"primary"}],"cwes":["CWE-88"],"updated_at":"2026-11-04T01:48:33.119303Z"}],"osv":[{"id":"CVE-2026-50014","title":"pnpm: Git Fetch Argument Injection via Lockfile resolution.commit","description":"pnpm is a package manager. Prior to 10.34.0 and 11.4.0, pnpm passes the lockfile-controlled git resolution.commit value to git fetch without 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=\u003ccommand\u003e. For SSH and local transports, --upload-pack can execute the supplied command. HTTPS transports ignore --upload-pack, so the practical attack surface is primarily SSH or local git dependencies. This vulnerability is fixed in 10.34.0 and 11.4.0.","status":"published","published":"2026-06-25T16:51:16.652Z","modified":"2026-11-05T02:31:10.812606739Z","cvss":[{"version":"3.1","score":6.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:H/I:H/A:N","level":"medium"}],"cwes":["CWE-88"],"updated_at":"2026-11-07T03:08:06.729372Z"},{"id":"GHSA-p4xf-rf54-rj3x","title":"pnpm: Git Fetch Argument Injection via Lockfile resolution.commit","description":"## Summary\n\npnpm passes the lockfile-controlled git `resolution.commit` value to `git fetch` without 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=\u003ccommand\u003e`. For SSH and local transports, `--upload-pack` can execute the supplied command. HTTPS transports ignore `--upload-pack`, so the practical attack surface is primarily SSH or local git dependencies.\n\n## Vulnerability Details\n\nThe vulnerable path is in `fetching/git-fetcher/src/index.ts`. When a git dependency host is configured for shallow fetching, pnpm calls:\n\n```typescript\nawait execGit(['fetch', '--depth', '1', 'origin', resolution.commit], { cwd: tempLocation })\n```\n\nBecause `resolution.commit` is appended before a `--` separator, Git can parse a commit value beginning with `-` as an option. The same file later passes the value to `git checkout` without a separator:\n\n```typescript\nawait execGit(['checkout', resolution.commit], { cwd: tempLocation })\n```\n\n`resolution.commit` comes from the lockfile and is typed as a plain `string`; pnpm does not validate it as a 40-character hexadecimal commit before passing it to Git.\n\n## Proof of Concept\n\n```bash\nbash autofyn_audit/exploits/vuln11_git_upload_pack_rce/exploit.sh\n# Creates a local bare git repo and triggers the shallow-fetch path.\n# Replaces the lockfile commit hash with '--upload-pack=touch /tmp/vuln11_pwned'.\n# Result: PASS -- /tmp/vuln11_pwned created by injected touch command.\n```\n\nThe PoC uses a local `file://githost/...` repository because the injection requires a local or SSH transport. HTTPS transport ignores `--upload-pack`.\n\n## Impact\n\nCode execution as the user running `pnpm install`, under specific transport conditions. The attacker must modify `pnpm-lock.yaml`, and the affected dependency must use SSH or local git transport. HTTPS transport (the common case) is immune.\n\n## Suggested Remediation\n\nAdd a `--` separator before lockfile-controlled git revision values. Validate `resolution.commit` matches `/^[0-9a-f]{40}$/i` before passing to Git.\n\n---\n\n\u003e Discovered by [AutoFyn](https://github.com/SignalPilot-Labs/AutoFyn)\n\u003e Full audit report: [audit_report.md](https://github.com/tempcollab/pnpm/blob/main/autofyn_audit/audit_report.md)\n\u003e Exploit script: [exploit.sh](https://github.com/tempcollab/pnpm/blob/main/autofyn_audit/exploits/vuln11_git_upload_pack_rce/exploit.sh)","status":"published","published":"2026-06-26T22:53:21Z","modified":"2026-06-26T23:11:29.682004Z","cvss":[{"version":"3.1","score":6.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:H/I:H/A:N","level":"medium"}],"cwes":["CWE-88"],"updated_at":"2026-11-02T15:46:52.534897Z"},{"id":"ROOT-APP-NPM-CVE-2026-50014","title":"CVE-2026-50014 in @rootio/pnpm - Patched by Root","description":"Root has patched CVE-2026-50014 in the @rootio/pnpm package for Root:npm. Multiple fixed versions available.","status":"published","published":"2026-07-30T10:40:28Z","modified":"2026-07-30T12:18:49.154030488Z","updated_at":"2026-11-02T15:53:27.649662Z"}]}}
