保护 NPM 供应链:safe-install 入门指南

Node.js 生态系统一直受到供应链攻击的困扰。软件包在安装期间运行任意脚本的能力——这一功能对于某些构建过程至关重要,但对开发者来说却是一个危险的漏洞——长期以来一直是一个重大的攻击向量。虽然像 Bun 这样的一些现代运行时已经引入了限制这些脚本的机制,但标准的 npm 生态系统在默认情况下在很大程度上仍然是开放的。

The Challenge of Install Scripts

许多 npm 软件包使用 preinstallpostinstallinstall 脚本来编译原生模块或执行初始设置。然而,这种机制允许依赖树中的任何软件包——包括深层的子依赖——在 npm install 过程中在您的机器上执行代码。如果一个软件包被攻破,恶意攻击者可以利用这些脚本窃取环境变量、SSH 密钥或将恶意代码注入您的构建流水线。

Introducing safe-install

为了填补原生 npm 功能中的这些空白,safe-install 被开发为一个轻量级工具,旨在为安装过程带来一定程度的细粒度控制。它专注于两个主要的安全性增强功能:

1. Trusted Build Dependencies

类似于 Bun 的 "trusted dependencies" 功能,safe-install 允许开发者默认禁用安装脚本,并维护一个显式的依赖项允许列表,仅允许这些依赖项运行其构建或安装脚本。这使得安全模型从 "allow all" 转向 "deny all, allow some",从而显著降低了项目的攻击面。

2. Blocking Exotic Sub-dependencies

借鉴了 pnpm 的 blockExoticSubdeps 设置,safe-install 提供了阻止奇异子依赖项的能力。这可以防止安装在 package.json 中未明确声明或在依赖树中以其他方式出乎意料的软件包,从而减轻了依赖混淆或恶意软件包隐蔽添加的风险。

Alternative Approaches to Supply Chain Security

虽然 safe-install 为本地保护提供了一个以开发者为中心的工具,但社区讨论强调了不同规模的开发需要不同的策略。

Enterprise-Grade Repository Management

对于大型组织,标准做法通常是完全放弃 "cowboy installs"。Nexus 和 Artifactory 等工具充当内部镜像和代理。在这种模式下,开发者不再直接从公共 npm 注册表获取软件包,而是从内部仓库中获取,其中仅托管经过 IT 验证和安全审查的软件包。 \n### Artifact Mirroring

对于那些在简单实用程序和完整的企业级仓库之间寻求折中方案的人来说,像 artifact-keeper 这样的制品镜像工具提供了一种把关软件包的方式。这些工具提供了一种更结构化的方式来管理哪些版本的哪些软件包被允许进入环境,从而在公共注册表和本地开发环境之间提供了一层隔离。

Conclusion

保护 npm 供应链的安全是多层次的工作。无论是通过 safe-install 进行细粒度的脚本控制,还是在 Artifactory 中实施严格的内部镜像,亦或是使用专门的制品保管器,目标始终如一:在安装阶段减少我们对第三方代码的信任度。

Sources