我们对 Homebrew 的审核
Our audit of Homebrew

原始链接: https://blog.trailofbits.com/2024/07/30/our-audit-of-homebrew/

William Woodruff 的文章讨论了对 Homebrew(适用于 MacOS 和 Linux 系统的流行包管理器)进行的安全审核的结果。 作者发现了 Homebrew 命令行界面 (CLI) 及其持续集成/持续部署 (CI/CD) 系统中的漏洞。 他们发现攻击者有可能在意想不到的地方将可执行代码插入 Homebrew 的操作中,从而破坏其预期的沙箱功能。 此外,他们还发现了 Homebrew 验证公式下载方式的弱点,允许攻击者修改公式的二进制(“瓶子”)构建,并可能获得对 CI/CD 工作流程执行的控制并窃取敏感信息。 此次审计由开放技术基金资助,作为其确保互联网基础设施关键组件安全的更广泛目标的一部分。 完整的报告可以在他们的出版物存储库中找到。 总体而言,作者得出的结论是,尽管 Homebrew 的代码库已经过彻底测试,但其广泛的 API 和松散的本地行为契约为攻击者引入非沙盒的本地代码执行提供了许多机会,尽管其核心假设是可信公式,但仍可能导致攻击。 总之,社区必须解决已发现的问题,以确保 Homebrew 和相关软件生态系统的持续安全。

开源包管理平台在确保其来源的公式准确性和可信度方面面临挑战。 例如,用户可能担心他们的brew更新是否引用合法、可信的来源,或者他们的公式是否错误地指向不同的来源。 此外,当域被接管时,就会出现问题,从而导致公式完整性的不确定性。 开发团队对不可信来源的快速响应对于降低风险至关重要。 用户可能对通过 Homebrew、npm、Winget 和 Choco 等平台提供的方法更新公式充满信心,但仍然担心潜在的拼写错误事件会导致不需要的恶意软件。 此外,必须及时解决 NPM 类型的漏洞。 相比之下,像 apt 和 yum 这样的商业存储库由于其受控环境而造成的此类问题较少。 使用 Nix 时,必须检查每个公式的薄片属性,尤其是在存在默认值时。 然而,拼写错误仍然是一个风险。 例如,在下载控制台模拟器 Cmder 时,可能会包含意外的恶意文件。 为了解决这个问题,社区内的开发人员和用户应该共享有关审查流程的明确指导和说明。 此外,像 MacPorts 这样的替代包管理系统具有独特的优势,例如易用性、与文件系统层次结构标准 (FHS) 的兼容性以及在主树之外构建临时包的能力。 与 Homebrew 相比,MacPorts 提供了更高的可靠性,特别是其选择器和变体,使其对于管理系统的特定方面具有吸引力。 总之,虽然包管理系统之间的选择归结为个人喜好,但开发人员必须优先考虑透明度、清晰的沟通和用户信任,以确保所选解决方案的安全性和效率。 开发人员和用户应该共同努力防止拼写错误事件并迅速解决漏洞,以最大限度地减少与包管理平台相关的风险。
相关文章

原文

By William Woodruff

This is a joint post with the Homebrew maintainers; read their announcement here!

Last summer, we performed an audit of Homebrew. Our audit’s scope included Homebrew/brew itself (home of the brew CLI), and three adjacent repositories responsible for various security-relevant aspects of Homebrew’s operation:

We found issues within Homebrew that, while not critical, could allow an attacker to load executable code at unexpected points and undermine the integrity guarantees intended by Homebrew’s use of sandboxing. Similarly, we found issues in Homebrew’s CI/CD that could allow an attacker to surreptitiously modify binary (“bottle”) builds of formulae and potentially pivot from triggering CI/CD workflows to controlling the execution of CI/CD workflows and exfiltrating their secrets.

This audit was sponsored by the Open Tech Fund as part of their larger mission to secure critical pieces of internet infrastructure. You can read the full report in our publications repository.

Homebrew

Homebrew is the self-described “missing package manager for macOS (or Linux).” It serves as the de facto standard package manager for software developers on macOS, and serves hundreds of millions of package installs annually. These installations include “keystone” packages such as Golang, Node.js, and OpenSSL, making Homebrew’s security (and the integrity of its builds) critical to the security of downstream software ecosystems as a whole. Homebrew’s core (not to be confused with homebrew-core) is a Ruby monolith responsible for providing the brew CLI to users along with an importable Ruby API.

Since its inception in 2009, Homebrew has undergone several architectural shifts aimed at improving the reliability and usability of packages delivered to users: binary builds (bottles) were implemented, made into the default installation mechanism (replacing local source builds), and subsequently built solely on CI/CD to limit the risk of a compromised developer machine. Despite this increasingly static approach, Homebrew’s core codebase is fundamentally dynamic and, in many places, reflects Homebrew’s historical need for dynamic loading of DSL-specified formulae via user-controlled Ruby code.

Scope

Homebrew is both a user-installable package manager (the brew CLI) and a packaging ecosystem, with an extensive and bespoke CI/CD configuration for reviewing, building, and distributing bottles to end users. Our audit focused on aspects of both of these, and aimed to answer questions like (but not limited to) the following:

  • Can a local actor induce unexpected execution of a formula’s DSL, e.g. without an explicit invocation of brew install?
  • Can a local actor induce unexpected evaluation of a tap’s formulae, e.g. from just brew tap with no subsequent user actions?
  • Can a local actor induce namespace confusions or conflicts within brew, resulting in brew install foo installing an unexpected formula?
  • Can a locally installed formula surreptitiously subvert or bypass Homebrew’s build isolation mechanisms?
  • Can an unprivileged or low-privilege CI/CD actor (such as a third-party contributor) pivot to a higher privilege in Homebrew’s CI/CD?
  • Can an unprivileged or low-privilege CI/CD actor surreptitiously taint or compromise a bottle build?
  • Can an unprivileged or low-privilege CI/CD actor establish persistence in Homebrew’s CI/CD?

Highlighted findings

brew

During our review of the brew CLI’s codebase, we uncovered a number of findings that, while not critical, could potentially undermine Homebrew’s per-formula integrity and isolation properties. We also uncovered findings that could allow loading of formulae (i.e., executable code) from surprising sources, such as remote URLs.

Some findings of interest include:

  • TOB-BREW-2, wherein a formula can influence the construction of its sandbox through string injection, resulting in a sandbox escape.
  • TOB-BREW-5, wherein Homebrew used a collision-prone hash function (MD5) for a synthetic namespace (FormulaNamespace) could allow an attacker to induce runtime confusion between formulae.
  • TOB-BREW-8, wherein a formula can surreptitiously include networked resources in its build without explicitly listing them via resource stanzas.
  • TOB-BREW-11, wherein a formula can potentially use a socket pivot to escape its build sandbox on macOS.
  • TOB-BREW-12, wherein a formula could opportunistically perform a privilege escalation through a user’s previously activated sudo token.
  • TOB-BREW-13, wherein brew install can be induced to install formulae from non-local URLs for any protocol supported by the version of curl being used, such as SFTP or SCP.

Our overall evaluation of Homebrew/brew is reflected in our report: while extensively tested, Homebrew’s large API and CLI surface and informal local behavioral contract offer a large variety of avenues for unsandboxed, local code execution to an opportunistic attacker. These avenues do not necessarily violate Homebrew’s core security assumptions (which assume trustworthy formulae), but may be subverted either by malicious formulae or through unexpected sources of formula loading (such as insufficiently sanitized inputs).

Homebrew’s CI/CD

Our review of Homebrew’s CI/CD workflows and actions uncovered findings that, while not critical, could undermine the integrity of Homebrew’s CI/CD runs and allow a less-privileged user to pivot to a position of higher privilege or even obtain persistence on Homebrew’s self-hosted GitHub Actions runners.

Some findings of interest include:

  • TOB-BREW-18, wherein multiple CI/CD workflows use the pull_request_target trigger to allow third-party pull requests to run code in the context of Homebrew’s upstream repository, potentially enabling either credential disclosure or tampering with Homebrew’s bottle builds.
  • TOB-BREW-23, wherein multiple CI/CD workflows inadvertently allow shell injection via unsanitized workflow_dispatch inputs, potentially enabling vertical movement by a less-privileged user (i.e., one who can dispatch workflows but not modify them).

Beyond CI/CD-specific findings, many brew findings are also salient in the CI/CD setting:

  • TOB-BREW-6, which describes a lack of sandboxing/isolation during archive extraction, could be used by a less-privileged CI actor to pivot into a higher-privileged context by inducing extraction of a formula or other executable code that gets auto-loaded and executed during the CI’s lifecycle.
  • TOB-BREW-13, described above, could be used by a less-privileged CI actor to pivot into a higher-privileged context, by inducing arbitrary code execution through brew install of a formula not present in the CI’s pre-configured (presumed trusted) context.

Our report concludes that Homebrew’s CI/CD, while mature and effective at reducing the number of human touch-points in Homebrew’s package lifecycle, is complex and relies on misuse-prone patterns common in GitHub Actions workflows (such as dangerous workflow triggers and mixing of configuration, code, and data via template expansion). These patterns do not necessarily enable persistence or pivoting by a fully external actor, but may be leveraged by a lower-privileged insider (such as a rogue maintainer) to undermine the integrity and isolation assumptions made by Homebrew’s CI/CD.

Takeaways

Auditing a package management ecosystem such as Homebrew poses unique challenges. Local package management tools install and execute arbitrary third-party code by design and, as such, typically have informal and loosely defined boundaries between expected and unexpected code execution. This is especially true in packaging ecosystems like Homebrew, where the “carrier” format for packages (formulae) is itself executable code (Ruby scripts, in Homebrew’s case).

Throughout the audit, we worked closely with the Homebrew maintainers and the Homebrew PLC and would like to thank them for sharing their extensive knowledge and expertise. We would also like to thank Patrick Linnane, Homebrew’s security manager, in particular for his triage and coordination efforts on behalf of Homebrew.

联系我们 contact @ memedata.com