艾体宝产品 | 通过 Mend Renovate 构建更安全的 npm 生态系统

10 阅读5分钟

在过去一年中,我们见证了多起重大攻击事件,例如 Shai-Hulud 蠕虫攻击、Nx 构建系统被攻破,以及通过 tj-actions/changed-files 漏洞导致机密信息泄露到公开的 GitHub Actions 日志中。但仅仅是罗列各种攻击事件,就足以占据本文的全部篇幅,更不用说深入探讨了。

作为一个行业和生态系统,我们能感受到攻击频率的日益增加。仅在 2024 年,报告的恶意软件包数量就同比增长了 156%。鉴于 Mend 托管的 Renovate Cloud 平台受信于超过 130 万个代码仓库,我们在保护开源软件消费者方面处于非常有利的地位,同时也为自托管 Renovate 的用户提供了更强的安全默认设置。在一系列备受瞩目的 npm 供应链安全攻击之后,Mend Renovate 的维护者们决定,对于选择采纳“最佳实践”配置的用户,默认启用这项安全功能是最佳选择。

为了帮助客户更好地应对这些日益增多的攻击,维护团队正在 Mend Renovate 现有的“最佳实践”配置之上进行构建。该团队一直致力于提供更多“默认即安全”的配置,并首先从 npm 生态系统着手。

在最新的 Mend Renovate 42 版本中,使用“最佳实践”配置的用户将会发现,npm 生态系统中的依赖项更新现在需要通过一个“最短发布时间”的检查,即某个更新发布后必须经过 3 天的窗口期,Mend Renovate 才会提议进行更新。通过这种方法,组织可以确保只有经过验证的、稳定的和值得信赖的依赖项更新才能进入生产环境,从而在保持开发者效率的同时,最终降低供应链攻击的风险。

这有何帮助?

尽管影响广泛,但这些攻击通常利用了两种常见情况:

  • 依赖项的精确版本未被锁定。
  • 依赖项的精确版本已被锁定,但我们在其发布后极短时间内就尝试更新。

不锁定依赖项版本可能有其合理的原因。例如,在 npm 生态系统中,当你发布一个拥有若干依赖项且被许多其他包所依赖的包时。

如果每次你提升一个依赖版本都需要发布自己的包,那么所有依赖于你的包也同样需要提升版本并发布新版,从而在整个生态系统中引发连锁效应。

其中一些过程可以通过自动化来简化——自然是使用像 Mend RenovateGitHub 的 Dependabot 这样的工具,但这仍然需要一定程度的人工审查。

与此同时,不锁定我们的依赖项可能会导致问题,用户可能会立即开始下载一个包的新版本。

在推荐锁定依赖版本后,下一个问题是我们应该多久更新一次。许多工具中现有的默认设置是“一旦有新版本就立即更新”,这可能导致一个恶意升级在其发布几分钟内就被创建为拉取请求 (Pull Request)。

尽管那个恶意的依赖项可能不会进入您开发人员的机器——但它有可能从您的自动化构建管道中窃取机密或其他特权信息——或者利用您 AI 驱动的代码审查工具中的提示注入漏洞。

如果我们增加软件包发布与它出现在您项目的拉取请求中的时间间隔,这就为安全研究人员和自动化安全工具提供了更多时间来发现软件包中的恶意意图,从而减少供应链攻击的可能性。

Mend Renovate 如何助力保障整个生态系统的安全

如上所述,在 Mend Renovate 的最新版本中,我们为所有使用“最佳实践”配置的用户启用了“最短发布时间”检查的强制执行。这适用于更新任何使用 npm 数据源的包,无论其使用的是何种 JavaScript/TypeScript 包管理器。

这项强制执行将:

  • 确保给定的依赖项更新包含其发布时间的元数据(“发布时间戳”)。
  • 确保在该版本发布后未满最少 3 天之前,不会创建任何分支。

如果发现不满足此要求的包更新,Mend Renovate 的依赖项仪表板中将包含一个“等待状态”的条目,并且需要人工明确请求才能更新——从而确保只有“安全”的包更新才会被提出。

(这里的一个告诫是,增加等待时间并不一定意味着所有问题都能被发现——由于针对性攻击或复杂的规避技术,所有问题可能无法都被捕获。)

通过将此功能直接添加到我们的“最佳实践”配置中,那些已经选择遵循行业最佳实践的用户将默认受到保护。而其他所有人也能够添加此功能,例如:

codeJSON

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["security:minimumReleaseAgeNpm"]
}

此外,还可以调整此行为——将等待窗口设置得任意长或短——或者对受信任的内部开发包绕过“最短发布时间”功能。

更多详情,请查阅专门的最短发布时间文档

纵深防御

除了让 Mend Renovate 在满足特定条件(即经过一个给定的窗口期)前不发起更新之外,我们还建议建立多层防御:

在可能的情况下,在您的包管理器中启用此功能,以保护开发人员的机器;和/或在您的自动化构建管道中启用此功能,在发布窗口期过去之前使构建失败。

在撰写本文时,pnpm 10.6yarn 4.2.0 已添加了对这些功能的支持,我们也看到其他包管理器正在考虑添加类似功能。

下一步计划?

继此版本的工作之后,维护团队将继续研究其他包生态系统,以便为我们的“最佳实践”配置启用相应功能,从而进一步保障面向消费者的产品和内部开发环境的安全!