RubyGems 为 Bundler 新增已发布包冷却机制

RubyGems 为 Bundler 新发布的 Gem 添加冷却功能

RubyGems 和 Bundler 4.0.13 引入了可选的冷却功能,可延迟新发布的 gem 在依赖解析期间的处理。

RubyGems 和 Bundler 4.0.13 引入了可选的冷却功能,可以延迟安装新发布的 gem 版本,为 Ruby 的包管理工作流程带来基于时间的供应链防御。

该功能允许开发者配置 Bundler,使其不会解析到发布时间不足指定天数的 gem 版本。在 RubyGems 维护者 Hiroshi SHIBATA 发布的示例中,项目可以直接在其 Gemfile 中添加冷却配置:

source "https://rubygems.org", cooldown: 7

启用该设置后,Bundler 会跳过最近七天内发布的 gem 版本,选择冷却窗口之外可用的版本。冷却功能默认未设置,因此现有项目将继续解析到最新的可用版本,除非明确启用该设置。

该功能针对的是一个具体但反复出现的供应链风险:恶意包版本发布后的初期。在许多攻击场景中,攻击者依赖速度。攻击者接管维护者账户,发布恶意版本,自动化安装或 CI 任务可能在维护者、注册管理机构或安全研究人员来不及响应之前就已获取该版本。

冷却功能如何改变解析行为

冷却功能不会判断 gem 是否安全。它只会延迟解析配置策略下过新的版本。

基于时间的安装延迟可以减少暴露于新发布的恶意版本的风险,但也可能阻碍合法版本的获取,包括紧急安全修复。 Bundler 为此类情况提供了紧急出口:通过传递 --cooldown 0 可以禁用延迟,允许项目在需要时安装最新可用版本。

该功能是包管理器添加安装时控制措施这一更广泛运动的一部分,这些控制措施旨在应对现代依赖攻击的速度。pnpm 引入了 minimumReleaseAge 来延迟依赖更新,npm 随后也添加了类似的 minimumReleaseAge 设置。RubyGems 的冷却功能将相同的理念应用于 Bundler 的解析器。

gem.coop 的冷却功能在注册层测试了类似的想法。这个独立的 RubyGems 兼容注册机构通过单独的 gem 源延迟访问新发布的 gem。Bundler 的实现采用了不同的方式:延迟在客户端的依赖解析过程中应用,使用 RubyGems.org v2 紧凑索引中的时间戳元数据。

Bundler 如何应用过滤器

Bundler 的冷却功能依赖于 RubyGems.org v2 紧凑索引中现已可用的每个版本的 created_at 元数据,Bundler 在依赖解析期间使用该索引。

RubyGems 未将此数据添加到其公共 API。该时间戳通过紧凑索引供 Bundler 使用,而非作为新的公共 gem 元数据字段供通用 API 消费者使用。

当 Bundler 拥有时间戳数据时,它会将 gem 版本的发布时间与配置的冷却期进行比较,并跳过仍在窗口期内的版本。如果 Bundler 无法证明某个版本太新,则不会阻止它。较旧的 gem 服务器、v2 切换之前的历史条目以及不暴露时间戳的私有注册机构仍然可以被解析。

这种保守行为避免破坏不提供新元数据的源,但也意味着该功能取决于 Bundler 能否查看给定源的发布时间戳。

配置选项

RubyGems 的公告描述了多种启用冷却功能的方式。最具项目特性的选项是 Gemfile 中源的 cooldown: 关键字。Bundler 还支持项目配置、全局配置、BUNDLE_COOLDOWN 环境变量,以及用于 bundle installbundle updatebundle addbundle outdated 的命令行标志。

每个源选项允许团队对不同注册机构应用不同策略。例如,项目可以延迟 RubyGems.org 的新版本,同时允许内部 gem 服务器立即解析:

source "https://rubygems.org", cooldown: 7

source "https://gems.internal.example.com", cooldown: 0 do gem "internal-tool" end

命令行标志优先于配置设置,配置设置优先于每个源的 Gemfile 设置。

Bundler 4.0.13 还使冷却功能在 bundle outdated 中可见。当存在更新的版本但仍处于配置的等待期内时,Bundler 会标注剩余的冷却时间,而非简单地将项目视为已更新。

RubyGems 扩展注册机构安全改进

冷却功能与 RubyGems 4.0.13 和 Bundler 4.0.13 一起发布,后者还包括其他增强功能和修复。在发布说明中,RubyGems 将冷却功能列在 Bundler 安全变更项下。

该功能遵循其他近期 RubyGems.org 安全工作,包括发布时 gem 验证、针对 Have I Been Pwned 的检查以防止重用被泄露的密码、强制双因素认证、受信任发布,以及由 Alpha Omega 和 Anthropic 支持的关键 gem AI 辅助漏洞扫描。

这些工作针对包供应链的不同环节。注册端检查可以帮助防止或检测恶意版本。身份验证改进使维护者账户更难被攻破。冷却功能让消费者有机会延迟采用刚出现的版本。

权衡在于,基于延迟的控制并不总是可取的。新发布的版本可能是恶意的,但也可能是紧急修复。Bundler 的实现通过使冷却功能成为可选的并允许在特定运行中禁用它,将该决定权留给项目。

RubyGems 的冷却功能在延迟安装成为应对快速移动包攻击的更常见响应之际,将这种控制带到了 Bundler。理念很简单:许多恶意版本在数小时内被检测和移除,而自动化安装几乎可以立即使用它们。短暂的等待期为检测和删除过程在版本进入项目依赖解析之前提供了更多工作时间。