加强 Quarkiverse 和 SmallRye 的发布流程

五月份,我们收到关于 SmallRye 发布流程中潜在泄露的警报。我们迅速采取行动缓解了问题;幸运的是,没有造成任何损害。尽管 Quarkiverse 没有报告泄露事件,但在我们的调查过程中,我们发现了一个更深层次的缺陷,它不仅影响了 SmallRye,也影响了 Quarkiverse。

在这篇博客文章中,我们将解释我们发现的漏洞,并为 Quarkiverse 和 SmallRye 仓库引入更安全的发布管道。

简而言之: 我们发现 Quarkiverse 和 SmallRye 的发布流程存在安全漏洞,这可能允许恶意行为者冒充项目并发布受损的制品。我们已经实施了一个新的、更安全的发布管道来解决这个问题。如果您是维护者,您已经收到一个合并到新流程的拉取请求。Quarkus 本身不受此问题影响,仅影响 SmallRye 和 Quarkiverse。

请立即采取行动,因为旧的发布流程将于 2024 年 10 月 16 日停用。请确保在此之前合并拉取请求,以避免发布中断。如果您有任何问题或疑虑,请通过 ZulipGitHub Discussions 联系我们。有关此变更的详细信息 如下

有关问题、解决方案以及如何适应的更多详细信息,请继续阅读!

漏洞:深入了解发布流程

要理解这个漏洞,首先勾勒出 Quarkiverse 和 SmallRye 最初使用的发布流程很重要。Quarkiverse 和 SmallRye 分别提供开发工具,以简化 Quarkus 扩展和 SmallRye 项目在 Quarkus 中的开发。对所有这些仓库没有中央监管;它们以自己的节奏独立发展。

这两个组织都使用 GitHub 仓库和 GitHub Actions 作为 CI 和自动化框架。发布项目的工作方式如下:

  1. 开发人员在仓库中打开一个拉取请求,更新项目 project.yaml 文件中的版本号(例如,请参阅 此 PR)。

  2. 常规构建工作流运行以确保其成功构建。还会运行一个特定的预发布流程来验证 YAML 文件格式是否正确。

  3. 一旦拉取请求被合并,就会触发发布工作流。

  4. 发布工作流首先“准备”发布。它将项目版本设置为配置的版本,并使用新更新的代码创建标签。它还会将主分支(或拉取请求的源分支)更新为下一个开发版本,并将此更改提交到分支。

  5. 准备步骤完成后,将检出标签,并创建发布制品。此阶段称为“发布执行”。在此阶段,从带标签的源代码创建二进制制品。制品会签名并推送到 Maven Central。

The release process used by Quarkiverse and SmallRye

最后一步“发布执行”是漏洞所在。原因如下:

  • 为了对制品进行签名,工作流使用组织范围的 GPG 密钥。

  • 为了发布制品,工作流使用组织范围的凭据。

The flaw in the release process

GPG 密码短语和 Maven Central 凭据存储在项目 GitHub 仓库的密钥中,但会在整个组织中共享。它们不易获得。您无法在日志中打印它们(需要一些技巧),也无法从 fork 中访问它们。

此时,一切似乎都正常。SmallRye 和 Quarkiverse 都为维护者提供了极大的自由来定制 GitHub Action 工作流以满足他们的需求。这种灵活性虽然强大,但也会带来风险。然后……我们就开始了……。

问题:凭据泄露(以及冒名顶替)的风险

我们说过密钥不易获得。那确实是真的,除了一个例外。项目中运行的 GitHub Actions(参见 Github Action 安全概述)可以访问它们。即使是测试也可以访问它们。在工作流期间运行的任何内容(actions、脚本……)都可以访问这些密钥……并泄露它们。

当开发人员在其工作流中包含外部或第三方 GitHub Action、Maven/Gradle 插件或 Junit 扩展时,该代码就可以访问组织范围的凭据。在仓库(非 fork)上工作流期间运行的任何代码都有可能泄露这些密钥。后果很严重:

  • 攻击者可以发布受损但看起来合法的项目版本,并使用组织的 GPG 密钥在 Maven Central 上签名。

  • 更糟糕的是,他们可以以 Quarkiverse 或 SmallRye 的名义将恶意制品推送到 Maven Central,冒充整个组织。

简而言之,通过访问这些凭据,攻击者可以冒充 Quarkiverse 或 SmallRye,绕过诸如签名提交或分支保护等典型保护。漏洞源于这些凭据是共享的,并且可供工作流期间运行的任何代码访问。

尽管迅速缓解了最初的 SmallRye 泄露事件,但发现这个更大的漏洞促使我们重新评估我们的发布流程。我们认为需要一种更安全、更具弹性的方法来防止未来的此类风险。

解决方案:新的发布流程

经过仔细考虑,我们得出结论,依赖组织范围的密钥进行发布已不再可行。我们需要一种更安全的方法。

起初,我们探索了使用仓库特定凭据的想法。虽然这可以限制泄露时的影响范围,但在大规模管理时会很困难,并且会减慢入职流程。此外,即使采用这种方法,单个仓库仍可能被泄露和冒充。因此,我们决定不采用此解决方案。

相反,我们设计了一个更健壮、更安全解决方案,涉及两个仓库:一个用于要发布的代码,另一个独立用于执行发布执行阶段本身。至关重要的是,包含源代码的仓库不再能访问组织范围的凭据——只有第二个仓库可以。

The new release process

当第二个工作流(红色)完成后,它会解除第一个工作流(蓝色)的阻塞。因此,您知道第二个工作流何时完成以及是否成功。

工作原理:分步说明

通过这种新方法,发布流程的初始阶段保持不变。现在发生的情况如下:

  1. 开发人员打开一个拉取请求,更新 project.yaml 文件中的版本号。

  2. 预发布工作流在仓库内触发,确保构建正确且版本已正确更新。

  3. 一旦拉取请求被合并,发布流程就与之前的方法有所不同:

    • 第一个仓库执行准备步骤,例如版本更新、标签创建和设置下一个开发版本。

    • 发布制品已生成,但未签名或推送到 Maven Central。

此时,将在一个单独的仓库中触发第二个工作流。这是关键操作发生的地方:

  • 第二个仓库包含必要的凭据(Maven Central 凭据和 GPG 密码短语),它会下载发布制品。

  • 它使用证明文件验证制品的完整性。

  • 然后,制品会签名并推送到 Maven Central。

第二个仓库对安全至关重要。它被锁定且不可修改,这意味着任何开发人员都无法自定义工作流或无意中引入漏洞。通过将敏感的发布步骤隔离在这个安全的环境中,我们大大降低了泄露或未经授权访问的风险。

这个新流程提供了急需的分离层,确保凭据保持安全,并大大降低了泄露的可能性。

平衡安全与开发者自由

如前所述,Quarkiverse 和 SmallRye 都非常重视赋能开发者,方法是最大限度地减少维护开源组件的开销。我们的新发布流程保持了这一理念,确保开发者仍然可以灵活地根据需要调整其组件仓库中的工作流。

开发者和维护者可以继续修改工作流、引入自定义 CI 步骤,并根据项目需求量身定制流程。唯一显著的变化是发布流程的一部分——关键的签名和发布步骤——现在在一个单独的、安全的环境中进行。

重要的是,维护者仍然可以随时从任何分支触发发布,就像以前一样。与第二个仓库的交接是无缝的,因此开发者的体验基本保持不变。

对于已深度定制发布管道的项目(例如,集成预发布验证或自动执行网站更新、发布说明生成或破坏性更改检测等任务),这种灵活性仍然得以保留。这些项目仍然可以触发

  • 当通过拉取请求更新 project.yaml 文件时,执行验证工作流。

  • 当创建新标签时触发的发布后工作流,允许文档更新或通知等任务继续进行,不受阻碍。

通过保留这种程度的自由,我们确保开发者能够根据项目的需求调整其工作流,同时受益于更安全的发布管道。

韧性:为意外做好准备

发布流程本质上是一个复杂的多步骤操作,有时会出错。虽然新的发布管道由于其拆分仓库的设计增加了另一层复杂性,但我们已经构建了系统韧性来缓解潜在问题。

为了解决这个问题,我们确保新流程是幂等的,这意味着它可以安全地重试而不会导致不一致或错误。如果在发布的任何点发生故障——无论是由于网络问题、构建失败还是制品验证问题——都可以从失败的工作流重新启动该过程。这使得发布能够继续进行,而无需不必要地重复之前的步骤。

此外,我们在发布流程的关键阶段内置了各种检查和验证,例如在进入下一阶段之前完成制品完整性验证(使用证明文件)。这些保障措施有助于降低发布不完整或错误的风险。

如果出现任何意外问题,组件仓库和安全发布仓库都提供详细的日志,使开发人员能够快速诊断和解决问题。这种透明度确保维护者即使在计划不如预期时也能保持控制。

这些措施旨在提供一个更具韧性、容错性强的发布流程,同时又不损害安全性或开发者体验。

行动呼吁:迁移到新的发布流程

如果您是 Quarkiverse 或 SmallRye 项目的维护者,您已经收到了一个更新您的项目到新的、更安全的发布流程的拉取请求。对于大多数维护者来说,此更新将是无缝的,不需要其他更改。

但是,如前所述,如果您的项目使用了自定义或更复杂的发布管道,您可能需要进行一些调整以确保与新系统的兼容性。这可能涉及更新处理预验证步骤、网站发布或发布说明生成的自定义工作流。请花时间审查和测试您仓库中的更改,以确保一切在新管道下都能正常工作。

重要时间线:旧发布流程的弃用

之前的发布流程现已弃用,并将于 2024 年 10 月 16 日完全阻止。在此日期之后,使用旧管道发布项目将不再可能。因此,您必须在此截止日期前采用新的发布流程拉取请求,以避免中断您项目的发布周期。

对于拥有更复杂设置的维护者,我们鼓励您尽快开始迁移,以确保平稳过渡。Roberto Cortez、George Gastaldi 以及 Quarkus 和 SmallRye 团队的其他成员将在您需要帮助时提供支持。

后续步骤

  • 审查拉取请求:检查您仓库中的自动拉取请求,并验证它是否将您的发布流程更新到新系统。

  • 合并更改:在弃用日期之前合并更改,以避免发布中断。

  • 测试您的工作流:如果您自定义了发布流程,请运行测试以确保在新管道下一切正常。

  • 寻求支持:如果您有任何问题或在迁移过程中需要帮助,请通过 ZulipGitHub Discussions 联系我们。

这个新的发布流程是提高 Quarkiverse 和 SmallRye 安全性的重要一步,您迅速采取迁移行动将有助于我们确保这些项目未来的一致性。

总结:对您来说没有变化——只是更安全了

从 Smallrye 和 Quarkiverse 开发者的角度来看,Quarkiverse 和 SmallRye 的发布流程基本保持不变。您仍然可以自由地修改工作流、自定义发布步骤并按需触发发布。您依赖的灵活性和控制力没有改变。

主要区别在于幕后:一个独立的、安全的仓库现在负责签名和发布您的发布等关键步骤。这意味着流程更加健壮,敏感凭据被锁定,泄露或冒名顶替的风险大大降低。

简而言之,虽然我们加强了发布管道的安全性,但我们以最小化中断的方式实现的。您将继续享受相同的开发者体验——只是现在,您还可以安心地知道您的发布比以往任何时候都更安全。

特别鸣谢

重新定义一个更安全、更可靠的发布流程并非易事,我们肯定无法在没有一些敬业且热情的开发者的支持下完成。我想对 George Gastaldi 和 Roberto Cortez 在整个过程中付出的辛勤努力表示衷心的感谢。您的奉献精神和专业知识是无价的。

我还想特别感谢 Andres Almiray,他在 JReleaser 方面的支持至关重要。没有他的积极响应和指导,新的发布流程是根本不可能实现的。