SocketDev / SocketDev/socket-cli

`socket pnpm install` fabricates alerts for packages not in the tree: pnpm v9 lockfile keys are truncated at the first underscore

未关闭
#1,489 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

主要语言
TypeScript
星标
317
派生
65
平均合并
1 小时 26 分钟
30 天内合并 PR
30

描述

Summary

The pnpm shadow wrapper's lockfile scan mangles the name of any package whose name contains an underscore, submitting a purl for a different, unrelated package. In any pnpm-v9 project that depends on string_decoder (i.e. effectively every project, via readable-stream), socket pnpm install reports a High CVE for string@3.3.3 — a package that is not in the dependency tree at all — and exits 1.

Mechanism

stripPnpmPeerSuffix truncates a lockfile package key at the first ( or _:

function stripPnpmPeerSuffix(depPath) {
  const parenIndex = depPath.indexOf('(');
  const index = parenIndex === -1 ? depPath.indexOf('_') : parenIndex;
  return index === -1 ? depPath : depPath.slice(0, index);
}

The _ case is the pnpm lockfile v5 peer-suffix convention (/foo/1.0.0_bar@2.0.0). In lockfile v9, package keys are plain name@version, where _ is an ordinary legal character in npm package names. So extractPurlsFromPnpmLockfile maps:

Lockfile key (v9) Submitted purl
string_decoder@1.3.0 pkg:npm/string (versionless, wrong package)
evp_bytestokey@1.0.3 pkg:npm/evp
@types/babel__core@7.20.5 pkg:npm/@types/babel

The batch purl endpoint resolves the versionless pkg:npm/string to the real (unrelated) string package, whose latest version 3.3.3 carries a High CVE — which the wrapper's default filter treats as fatal, regardless of org policy. The other two mangled names happen not to resolve to alerting packages, which is why only string@3.3.3 surfaces.

Reproduction

mkdir repro && cd repro
npm init -y > /dev/null
printf 'lockfileVersion: "9.0"\npackages:\n  string_decoder@1.3.0:\n    resolution: {integrity: sha512-zOgAKMkjXbleOl9U5k7DBVdNwCRJW8ANhbJpEbriDmqu3nrOJPVHHqAmU7hBVBkoGuZbSpUnGdgOSg74RSPikw==}\nsnapshots:\n  string_decoder@1.3.0:\n    dependencies:\n      safe-buffer: 5.2.1\n' > pnpm-lock.yaml
SOCKET_CLI_DEBUG=1 DEBUG='*' socket pnpm install 2>&1 | grep -A5 purls
# → purls include 'pkg:npm/string' (no version), and the run fails on string@3.3.3's High CVE

(Alternatively: any real pnpm-v9 project with string_decoder in its lockfile reproduces it — we hit it in a 1,500-package workspace.)

Versions

Observed identical in @socketsecurity/cli@1.1.85, socket@1.1.143, and socket@1.1.155 (latest as of 2026-08-08): dist/utils.js stripPnpmPeerSuffix, reached via extractPurlsFromPnpmLockfilegetAlertsMapFromPnpmLockfile in dist/shadow-pnpm-bin2.js's install path.

Suggested fix

Only apply the _ truncation to v5-style dep paths (those beginning with / and using /name/version shape), or key the suffix-stripping on the lockfile's lockfileVersion. For v9 name@version keys, peer suffixes only ever appear in parentheses.

Impact

  • socket pnpm install fails spuriously (exit 1) for effectively any pnpm-v9 tree containing an underscore-named package that maps onto an alerting package name.
  • The submitted purl set silently omits the real packages (string_decoder, evp_bytestokey, @types/babel__* are never actually checked).

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

使用所示的 pnpm v9 lockfile 重现该问题,然后检查 dist/utils.js 中的 stripPnpmPeerSuffix,以及它在 dist/shadow-pnpm-bin2.js 中通过 extractPurlsFromPnpmLockfile 和 getAlertsMapFromPnpmLockfile 的使用情况。完成的标准是:名称包含下划线的软件包在提交的 purls 中保留其完整名称和版本,针对相关的 lockfile 格式仍能处理 peer 后缀,并且重现过程不再报告无关的 string alert。

由索引模型根据 Issue 内容生成。

评估

技术栈
typescript
领域
cli, security
Issue 类型
缺陷
难度
3/5
预计耗时
1-2 天
活跃度
冷清
描述清晰度
基本清楚
新手友好度
66/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。