pnpm: Git Fetch Argument Injection via Lockfile resolution.commit
Date: 2026-06
Affected: npm/pnpm, npm/pnpm
Attack vector: rce
Category: vulnerability-disclosure
Severity: Medium
CVE: CVE-2026-50014
CWE: CWE-88
CVSS: 6.4 (CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:H/I:H/A:N)

## Summary 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=<command>`. 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. ## 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: ```typescript await execGit(['fetch', '--depth', '1', 'origin', resolution.commit], { cwd: tempLocation }) ``` Because `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: ```typescript await execGit(['checkout', resolution.commit], { cwd: tempLocation }) ``` `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. ## Proof of Concept ```bash bash autofyn_audit/exploits/vuln11_git_upload_pack_rce/exploit.sh # Creates a local bare git repo and triggers the shallow-fetch path. # Replaces the lockfile commit hash with '--upload-pack=touch /tmp/v


Mitigations:

Architectural layers (MAESTRO):