减轻供应链攻击
有时 npm 包会被破坏并发布带有恶意软件的版本。幸运的是,有像 Socket、Snyk、Xygeni 和 Aikido 这样的公司可以提前检测到这些被破坏的包。npm 注册表通常会在几小时内删除受影响的版本。然而,从恶意软件发布到被发现之间总有一段时间窗口,在此期间你可能会受到影响。幸运的是,你可以使用 pnpm 做一些事情来将风险降到最低。
🌐 Sometimes npm packages are compromised and published with malware. Luckily, there are companies like Socket, Snyk, Xygeni and Aikido that detect these compromised packages early. The npm registry usually removes the affected versions within hours. However, there is always a window of time between when the malware is published and when it is detected, during which you could be exposed. Fortunately, there are some things you can do with pnpm to minimize the risks.
阻止风险较高的安装后脚本
🌐 Block risky postinstall scripts
历史上,大多数被攻击的包都会使用 postinstall 脚本在安装时立即运行代码。为减轻这种风险,pnpm v10 禁用了依赖中 postinstall 脚本的自动执行。虽然可以通过 dangerouslyAllowAllBuilds 全局重新启用,但我们建议仅使用 allowBuilds 显式列出受信任的依赖。这样,如果某个依赖过去不需要构建,它在发布被攻击的版本时就不会突然运行恶意脚本。不过,我们仍建议在更新包含 postinstall 脚本的受信任包时保持谨慎,因为 [它可能会被攻破]。
🌐 Historically, most compromised packages have used postinstall scripts to run code immediately upon installation. To mitigate this, pnpm v10 disables the automatic execution of postinstall scripts in dependencies. Although there is a setting to re-enable them globally using dangerouslyAllowAllBuilds, we recommend explicitly listing only trusted dependencies using allowBuilds. This way, if a dependency did not require a build in the past, it won't suddenly run a malicious script if a compromised version is published. Still, we recommend being cautious when updating a trusted package that has a postinstall script, as it might get compromised.
防止出现特殊的传递依赖
🌐 Prevent exotic transitive dependencies
你可以通过将 blockExoticSubdeps 设置为 true 来防止传递依赖使用奇异来源(例如 git 仓库或直接的 tarball URL)。这确保所有传递依赖都来自可信来源,从而降低供应链攻击的风险。
🌐 You can prevent transitive dependencies from using exotic sources (like git repositories or direct tarball URLs) by setting blockExoticSubdeps to true. This ensures that all transitive dependencies are resolved from trusted sources, reducing the risk of supply chain attacks.
延迟依赖更新
🌐 Delay dependency updates
减少安装受损包风险的另一种方法是延迟更新你的依赖。由于恶意软件通常会被快速检测到,延迟 24 小时更新大多数情况下可以防止你安装到有问题的版本。minimumReleaseAge 设置定义了在 pnpm 安装某个版本之前,该版本发布后必须经过的最少分钟数。在 pnpm v11 中,默认值为 1440(1 天),这意味着新发布的包在至少 1 天后才会被解析。要选择退出,请在 pnpm-workspace.yaml 中设置 minimumReleaseAge: 0。你也可以将其设置为 10080,以便在安装新版本之前等待一周。
🌐 Another way to reduce the risk of installing compromised packages is to delay updates to your dependencies. Since malware is usually detected quickly, delaying updates by 24 hours will most likely prevent you from installing a bad version. The minimumReleaseAge setting defines the minimum number of minutes that must pass after a version is published before pnpm will install it. In pnpm v11, this defaults to 1440 (1 day), meaning newly published packages will not be resolved until they are at least 1 day old. To opt out, set minimumReleaseAge: 0 in pnpm-workspace.yaml. You can also set it to 10080 to wait one week before installing a new version.
使用 trustPolicy 强制信任
🌐 Enforce trust with trustPolicy
为了进一步保护你的供应链,pnpm 还支持 trustPolicy 设置。当设置为 no-downgrade 时,如果某个包的信任级别相较于之前的版本降低(例如,之前是由受信任的发布者发布的,但现在仅有来源信息或没有信任证据),该设置将阻止安装该包。这有助于你避免安装可能被破坏或信任度较低的版本。
🌐 To further protect your supply chain, pnpm also supports a trustPolicy setting. When set to no-downgrade, this setting will prevent installation of a package if its trust level has decreased compared to previous releases (for example, if it was previously published by a trusted publisher but now only has provenance or no trust evidence). This helps you avoid installing potentially compromised or less trustworthy versions.
如果你需要允许特定的软件包或版本绕过信任策略检查,可以使用 trustPolicyExclude 设置。这对于已知的软件包很有用,这些软件包可能不符合信任要求,但仍然可以安全使用。
🌐 If you need to allow specific packages or versions to bypass the trust policy check, you can use the trustPolicyExclude setting. This is useful for known packages that may not meet the trust requirements but are still safe to use.
此外,trustPolicyIgnoreAfter 设置允许你忽略对已发布超过指定时间的包的信任检查。这对于缺乏使用签名或来源进行发布流程的旧版本包非常有用。
🌐 Additionally, the trustPolicyIgnoreAfter setting allows you to ignore trust checks for packages published more than a specified time ago. This is helpful for older versions of packages that lack a process for publishing with signatures or provenance.
使用 lockfile
🌐 Use a lockfile
不言而喻,你应该始终使用锁文件来锁定你的依赖。将锁文件提交到你的代码仓库,以避免意外的更新。
🌐 It goes without saying that you should always lock your dependencies with a lockfile. Commit your lockfile to your repository to avoid unexpected updates.