pnpm audit 报告高危漏洞但不知道怎么修复怎么办?
我用 pnpm 管理项目依赖,今天运行 pnpm audit 时发现好几个高危漏洞,但提示信息太模糊了,根本不知道该升级哪个包或者怎么处理。
比如它说某个间接依赖有原型污染问题,但我查了 package.json 里根本没有这个包,应该是被其他依赖带进来的。我试过 pnpm update,但漏洞还在。有没有办法定位到具体是哪个依赖引入的,然后精准修复?
pnpm audit
# 输出类似:
# High severity vulnerability found in some-deep-dep
# Package: some-deep-dep
# Patched in: >=2.1.0
# Dependency of: my-direct-package
# Path: my-direct-package > another-dep > some-deep-dep
根本原因是你的直接依赖 my-direct-package 或者 another-dep 在 package.json 里声明的版本范围太宽了,导致 pnpm 在解析依赖树时拉取了一个有漏洞的旧版本 some-deep-dep。pnpm update 默认只升级你 package.json 里写明的直接依赖,它不会为了修复深层依赖而去强制改变直接依赖的版本,或者去提升一个间接依赖的大版本号,因为这可能导致直接依赖不兼容。
先别急着升级大包,用 pnpm 的 overrides 功能是最精准的修复办法。这招比 npm 的 resolutions 强,它是强制性的。你不需要去升级那个直接依赖,只需要告诉 pnpm:不管谁要引用 some-deep-dep,统统给我用修复后的版本。
第一步,先用 pnpm why 把这个幽灵依赖揪出来,确认它到底是谁引过来的,以及有没有多个地方在用。在终端运行:
pnpm why some-deep-dep这个命令会打印出完整的依赖树,你能看到所有引用它的路径。如果发现只有一个路径引用了它,那就好办,直接覆盖它。
第二步,打开你的 package.json,找到根目录下的 pnpm 配置段(如果没有就加一个),或者直接在根层级加 overrides 字段。
注意看代码里的注释。这里的 some-deep-dep 必须和 pnpm audit 报出来的 Package 名字完全一致。版本号 >=2.1.0 是根据审计报告里的 Patched in 字段填的。
配置完之后,你需要重新安装依赖才能生效。运行:
pnpm install --force为什么要加 --force?因为 pnpm 为了性能,有时候会复用 lockfile 或者 store 里的缓存,强制重装能确保它重新解析依赖树,应用你的 overrides 规则。安装完后再跑一遍 pnpm audit,如果那个漏洞还在,可能是因为那个直接依赖 my-direct-package 自身就硬编码了对旧版本的要求(比如 peerDependencies 限制),导致 overrides 无法满足(比如直接依赖要求 some-deep-dep 必须是 1.x,而你 override 到了 2.x)。这时候就比较麻烦了,你得去升级 my-direct-package 本身,或者去它的 issue 区找找看有没有新版本。
如果 overrides 还搞不定,还有一个大招是用 pnpm 的 patch 功能,但这通常是用来改源码的,对于版本类漏洞,overrides 是标准解法。做前端开发就是这样,大部分时间都在跟这种破依赖做斗争,没办法,生态就这样。希望能帮你把那个高危红叉消掉。