1 ポイント 投稿者 GN⁺ 2024-07-31 | 1件のコメント | WhatsAppで共有
  • Trail of Bitsの監査では、macOS開発者エコシステムにおける事実上の標準パッケージマネージャーであるHomebrewで、予期しないコード実行とビルド完全性の低下につながる可能性が確認されたが、発見事項は致命的なレベルではなかった
  • 対象範囲は、brew CLIを含むHomebrew/brewに加え、Homebrew/actions、Homebrew/formulae.brew.sh、Homebrew/homebrew-test-botまで含み、ローカルのパッケージマネージャーとCI/CDの境界をあわせて調査した
  • brew側の問題は、サンドボックス設定文字列のインジェクション、MD5ベースの名前空間衝突、明示されていないネットワークリソースの取り込み、macOSでのソケットピボット、sudoトークンの悪用、非ローカルURLベースのformulaインストール可能性につながった
  • CI/CDでは、pull_request_targetトリガーと検証されていないworkflow_dispatch入力が、bottleビルドの改ざん、認証情報の露出、権限昇格、self-hosted GitHub Actions runnerでの永続化確保の経路になり得た
  • Homebrewは信頼できるformulaを前提としているが、formula自体がRuby実行コードであり、API・CLIの表面が広いため、隔離と完全性の境界を一貫して維持するのは難しい

監査範囲と対象

  • Trail of Bitsは昨夏、Homebrewの監査を実施した
  • 監査対象は、brew CLIを含むHomebrew/brewと、セキュリティ上重要な隣接リポジトリ3つだった
    • Homebrew/actions: HomebrewのCI/CD全般で使われるカスタムGitHub Actionsリポジトリ
    • Homebrew/formulae.brew.sh: インストール可能なパッケージのJSONインデックスを担当するコードベース
    • Homebrew/homebrew-test-bot: Homebrewの中核的なCI/CDオーケストレーションとライフサイクル管理ルーチン
  • Open Tech Fundが、インターネットインフラの中核構成要素のセキュリティを強化する活動の一環として監査を支援した
  • 完全なレポートはTrail of Bitsのpublicationsリポジトリで確認できる

Homebrewが重要な理由

  • Homebrewは「macOSまたはLinuxのための不足しているパッケージマネージャー」を掲げ、macOS開発者にとって事実上の標準パッケージマネージャーの役割を担っている
  • 毎年数億件のパッケージインストールを処理しており、インストール対象にはGolang、Node.js、OpenSSLのような中核パッケージも含まれる
  • こうしたパッケージのビルド完全性は、Homebrewを超えて下流のソフトウェアエコシステムのセキュリティにつながる
  • Homebrewのcoreは、brew CLIと利用可能なRuby APIを提供するRubyモノリスである
  • 2009年の開始以降、Homebrewはパッケージの信頼性と使いやすさを高めるため、構造を何度も変更してきた
    • バイナリビルドであるbottleを導入した
    • ローカルソースビルドに代わり、bottleをデフォルトのインストール方式にした
    • 侵害された開発者マシンの影響を減らすため、bottleはCI/CDでのみビルドされるようになった
  • インストール方式は次第に静的なものへ変わってきたが、中核コードベースには、ユーザー制御のRubyコードとしてDSLベースのformulaを動的にロードしていた歴史的構造が今も残っている

監査で見た攻撃境界

  • ローカルの行為者が明示的なbrew installなしに、formula DSLの予期しない実行を誘発できるかを確認した
  • ユーザーがbrew tapを実行するだけで、tapのformula評価が予期せず発生し得るかを検討した
  • brew install fooが想定と異なるformulaをインストールするよう、名前空間の混同や衝突を引き起こせるかを調べた
  • ローカルにインストールされたformulaが、Homebrewのビルド隔離メカニズムを密かに迂回または弱体化できるかも確認した
  • CI/CDでは、低権限の行為者がより高い権限へピボットしたり、bottleビルドを汚染したり、永続化を作れたりするかが中心的な問いだった

brew CLIで見つかった問題

  • brew CLIコードベースでは、formulaごとの完全性と隔離特性を弱め得る問題が見つかった
  • formulaがリモートURLのような予期しない出所からロードされ得る経路も確認された
  • 主な発見事項は次のとおり
    • TOB-BREW-2: formulaが文字列インジェクションによってサンドボックス設定を変更でき、サンドボックス脱出につながり得る
    • TOB-BREW-5: Homebrewが合成名前空間であるFormulaNamespaceに衝突可能なMD5ハッシュ関数を使用しており、攻撃者がformula間のランタイム混同を誘発できる
    • TOB-BREW-8: formulaがresource stanzaに明示しなくても、ネットワークリソースをビルドに密かに含めることができる
    • TOB-BREW-11: formulaがmacOSでソケットピボットを使い、ビルドサンドボックスの外へ出られる
    • TOB-BREW-12: formulaがユーザーの以前のアクティブなsudoトークンを通じて、機会主義的な権限昇格を実行できる
    • TOB-BREW-13: brew installが、使用中のcurlバージョンがサポートするSFTP、SCPなどすべてのプロトコルの非ローカルURLからformulaをインストールするよう誘導され得る
  • Homebrew/brewは広範にテストされているが、大きなAPI・CLI表面と非公式なローカル動作契約のため、攻撃者がサンドボックス外でローカルコードを実行する経路を見つける余地が多い
  • こうした経路は、信頼できるformulaを前提とするHomebrewの中核的なセキュリティ前提を必ずしも破るものではないが、悪意あるformulaや十分に精査されていない入力を通じた予期しないformulaロードに悪用され得る

Homebrew CI/CDで見つかった問題

  • HomebrewのCI/CDワークフローとアクションでも、CI/CD実行の完全性を弱め得る問題が見つかった
  • 低権限ユーザーがより高い権限の位置へピボットしたり、Homebrewのself-hosted GitHub Actions runnerで永続化を得たりする可能性が確認された
  • 主な発見事項は次のとおり
    • TOB-BREW-18: 複数のCI/CDワークフローがpull_request_targetトリガーを使用し、サードパーティのプルリクエストがHomebrew upstreamリポジトリのコンテキストでコードを実行できるようにしていた。これは認証情報の露出やbottleビルドの改ざんにつながり得る
    • TOB-BREW-23: 複数のCI/CDワークフローが、検証されていないworkflow_dispatch入力によるシェルインジェクションを許しており、ワークフローは変更できないが実行はできる低権限ユーザーの垂直移動につながり得る
  • CI/CD固有の問題に加え、brew関連の発見事項の一部はCI/CD環境で重要だった
    • TOB-BREW-6: アーカイブ展開中のサンドボックス化・隔離が不足しており、低権限のCI行為者が自動ロード・実行されるformulaや実行コードを展開させ、より高い権限コンテキストへピボットできる
    • TOB-BREW-13: CIが事前に構成した信頼コンテキストにないformulaをbrew installでインストールさせ、任意コード実行と権限ピボットに利用され得る
  • Homebrew CI/CDは、パッケージのライフサイクルにおける人手の介入点を減らすうえで成熟しており効果的だが、GitHub Actionsワークフローでよく見られる誤用されやすい脆弱なパターンに依存している
    • 危険なワークフロートリガー
    • テンプレート展開による設定、コード、データの混在
  • こうしたパターンは、完全な外部行為者による永続化確保やピボットを必ずしも可能にするものではないが、rogue maintainerのような低権限の内部者がCI/CDの完全性・隔離の前提を弱めるために利用し得る

パッケージマネージャー監査が難しい理由

  • Homebrewのようなパッケージ管理エコシステムは、設計上、任意のサードパーティコードをインストールして実行するため、監査境界が難しい
  • 想定されたコード実行と予期しないコード実行の区別も、概して非公式で緩く定義されている
  • Homebrewでは、パッケージの運搬形式であるformula自体がRuby実行コードであるため、この問題がより顕著になる
  • 監査プロセスでは、Homebrew maintainers、Homebrew PLC、Homebrewセキュリティ管理者のPatrick Linnaneと緊密に協力した

1件のコメント

 
GN⁺ 2024-07-31
Hacker News の意見
  • この記事の著者であり、監査に参加した者の一人なので質問に答えられる
    監査報告書そのものが見つけにくいなら間接リンクなので、コピーもここに置いておく: https://github.com/trailofbits/publications/blob/eb9344f2261...

  • 素晴らしい仕事で、こうしたオープンソースソリューションでまさに探していたのは、このような体系的なレビューだった
    コードレビューの焦点ではないのだろうが、オープンソースのパッケージ管理プラットフォームに内在する全般的なサプライチェーンのライフサイクル問題についての見解が気になる。新しい formula が正しい上流を指していることを保証する検証プロセスは適切なのか、ユーザーは brew update が今も信頼できる上流を参照しているとどう確信できるのか、ドメインが乗っ取られたらどうなるのか、formula の信頼できない上流にチームがどれほど迅速に対応できるのか、という点が核心になる
    こうした問題のすべてを Homebrew が解決すべきというわけではないが、エコシステムの観点では重要な検討事項だ。winget や choco にも同じ問題があり、apt や yum のような商用サポート付きリポジトリでは比較的少ない。個人的にも、多くの管理者にとっても、Windows Store を扱う際の大きな懸念でもある
    最後に Homebrew チームが見ているなら、npm 風の脆弱性通知があると本当にありがたい

    • この問題は、特にパッケージマネージャが本番環境や CI/CD パイプラインで使われるときに非常に深刻だ
      中国共産党の関係者が主要パッケージへの pull request 権限を得た公開事例も十分にあるし、公開されていない、あるいは握りつぶされた事例はもっと多いと思う。評判の良い主体からあまり知られていない個人へパッケージ所有権が移るだけでも、当然ながら心配になる
      ソフトウェアエンジニア/エンジニアリングマネージャから VC になった立場として、こうした保証を提供するスタートアップや商用企業があるのか気になる。ただ、この問題を解決する市場規模が、独立した事業になるほど十分ではないのではないかとも懸念している
  • Nix に移る前は、当時 Homebrew がかなり独特な動きをしていたので MacPorts を使っていた。マルチユーザー設定ではうまく動かず、/usr/local を所有し、自動更新とバージョン管理の欠如のせいで「自分のコンピュータでは動く」問題が多かった
    Homebrew でいつも不安に感じていたのは、Git ではなく GitHub URL を一時的なパッケージのように使える点だった。TOB-BREW-13 がその方式で動作したのか気になる。その機能はずっと、セキュリティ事故が起きるのを待っているだけのものに聞こえていた
    いずれにせよ、macOS における Nix の監査も見てみたい。特に nix develop と関連コマンドの動作方式に欠陥があるのかが気になる

    • 自分も Homebrew -> MacPorts -> Nix の順に移ったので面白い
      Homebrew には分析データ収集があり、バージョンがあまりにも頻繁に壊れた。MacPorts ははるかに安定しているが、一部のニッチなパッケージはうまくビルドされず、tmux で terminfo の問題があった
      Nix はこうした多くを再定義でき、Debian ワークステーションと home manager 設定を共有できるので良い
    • Nix は macOS ではデフォルトでビルドサンドボックスを使わない。nix.confsandbox = true を入れて自分で有効化することはできるが、あれこれ壊れる可能性がある
      Nix のサンドボックスも、実のところセキュリティ境界として設計されたものではない。サンドボックス脱出を防ぐための努力は入っておらず、ホストの多くのものがサンドボックス環境へ漏れ込む。信頼できないパッケージをビルドするなら、gVisor や完全な VM のようなものが必要だ
    • Nix も github を許可している
  • サンドボックス脱出バグと関連修正をざっと見た: https://github.com/Homebrew/brew/pull/17700/commits/f4e5e0c7...
    これで合っているのか疑問だ。サンドボックスプロファイルに補間されて問題を起こすのを防ごうとしているようだが、この文字リストについてどれほど確信できるのか分からない

    • コミットメッセージがその質問に答えられたはずなのに、実際には diff がすでに示している「サンドボックスルールのパスに特殊文字を許可しない」を繰り返しているだけだ
      なぜそうするのか、禁止した特定の文字に何が特別なのかを説明していない。より良いメッセージなら「そうしないと ... のため、パス内の特定の文字を防ぐ。これらの文字は注意が必要だが、他の文字は問題ない理由は ...」といった内容を含んでいただろう
      今このコードを書いていて何をしているか分かっていたとしても、1年後に見返したら、なぜこの変更をしたのか首をかしげることになるだろう
      良いコミットメッセージの実例はここにある: https://github.com/git/git/commit/92fe7c7d42cc941ed70d6fce98...
    • それが修正なら自分も驚く。ブラックリストより許可リストの方がよいのでは?
  • しばらく前に brewnix に乗り換えた。テキスト UI は、エンドユーザー向けの使いやすさをもっと改善できる
    そこで brew のように簡単に ixnay install できるように「ixnay」というラッパーまで作ったが(https://github.com/pmarreck/ixnay)、全体的な保証にはそれだけの価値がある

    • 自分も nix のコマンドラインは面倒だと感じている。これを一度試してみたい。組み込みの #help ドキュメントが気に入った
    • ixnay をもっと早く知っていたらよかった。自分もユーザー体験にいら立って、結局自作ツールを作った。名前は hdn: https://github.com/seasonedfish/hdn
      README に ixnay について触れておいた
  • ほぼすべての Linux や *BSD のパッケージマネージャと比べて、Homebrew にとって大きな低スキル攻撃面であるサプライチェーンの完全性が、あまり大きく扱われていないのは少し意外です。
    Homebrew のメンテナーは概してコミットやパッケージに署名せず、レビューやマージにも署名せず、コンパイル時に作者やレビュアーの署名を検証せず、別管理の CI でビルドを再現せず、GitHub でハードウェア 2 要素認証も強制していません。
    brew ユーザーのセキュリティ水準は、数百人いる brew メンテナーのうち、今日いちばん運用セキュリティが悪い人の水準に縛られます。
    さらに dependabot が自動でコミットを作るため、自分が制御する外部プロジェクトに悪意あるコミットを入れ、dependabot が Homebrew にアップグレードコミットを作るのを待ってから自分でマージすることもできます。Homebrew のメンテナーになるには実質的に検証がほとんどなく、簡単なバグをいくつか直せば済みます。
    メンテナーの期限切れメールドメインを 1 つ取得して、パスワードリセットメールを自分に送らせ、休暇中または活動を休んでいる人のアカウントを乗っ取ることもできます。
    誰かが気づく前に、数千社を侵害できる可能性は高いでしょう。
    正直なところ、権限のある会社支給機器では Brew を絶対に許可しません。数百人の任意の人物と、その脆弱な運用セキュリティを悪用する誰に対しても、ユーザーのシステムで任意コードを実行する能力を与えることになるからです。
    主要な Linux パッケージマネージャも、レビュー署名のような部分では十分に踏み込めていませんが、ほとんどは少なくとも作者レベルのパッケージ署名、人によるレビュー、多くのパッケージに対する独立した再現ビルドは行っています。
    企業のシステム管理者のような高価値ターゲットが、自分のコンピュータで brew を許可していることが多い点を考えると、Brew は不十分なサプライチェーン管理による被害という点で、いつ Crowdstrike を超えてもおかしくない軌道上にあります。

  • Mac で Pacman のように PKGBUILD を同程度の性能でサポートし、主要プログラムのパッケージがきちんと維持されるなら、Mac を使う際に利便性のために受け入れなければならない妥協はずっと少なくなると思います。
    Homebrew は素晴らしく、formula も本当によく維持されていますが、PKGBUILD の単純さ、同期の速さ、パッケージマネージャごとに多数の引数やフラグを覚えなければならない認知負荷の低さを考えると、pacman が Mac でそのまま動いてほしいです。

    • 標準の pacman は macOS では期待どおりに動きませんが、多少の修正やハックで動かそうとする試みがあります: https://github.com/liudongmiao/pacman, https://github.com/kladd/pacman-osx
    • こうした試みは何度かありました。その一部は実際に動いているかもしれません。
    • MacPorts がそれに相当するものではないのですか?純粋に気になります。
  • 主な攻撃ベクトルは、単に新しい formula をコントリビュートして、悪意ある新規パッケージをこっそり入れられる点だと思います。
    メンテナーチームは、新たにコントリビュートされるすべての formula を監査するには小さすぎます。この攻撃ベクトルが監査に含まれていないのは意外です。

    • 現在の Homebrew core formula のレビュアーたちは、自分たちのチームが新規の formula リクエストを十分に確認するには小さすぎるとは考えていないと思います。
      たとえそうだとしても、それは記事で明示的に扱われているパッケージングの曖昧さの 1 つです。ファーストパーティ実行とサードパーティ実行の境界は本質的に曖昧であり、意図してサードパーティコードを実行したときに起こる当然のことをすべて指摘するよりも、サードパーティ実行が予期しない場所で起こり得る箇所を見つけるほうが、セキュリティ上の価値は相対的に高いと思います。
      ただし、パッケージングエコシステム全体は、こうした承認プロセスについて検証されるべきだと思います。しかしそれは人間のプロセスに関するものなので、ソフトウェア監査というよりはレッドチーム型の監査に近いです。
    • その部分は書いてあり、formula は信頼できると仮定していました。
      “... These avenues do not necessarily violate Homebrew’s core security assumptions (which assume trustworthy formulae),...”
    • 私も数日前、「Cmder」というコンソールエミュレータを誰かがダウンロードしているのを見てぎょっとしました。複数の FOSS ツールをまとめたものなのですが、PowerShell スクリプト、Perl スクリプト、Python スクリプト、シェルスクリプト、DLL、EXE など、悪意があり得るファイルが文字どおり約 1,000 個ありました。
      結果的には無害でしたが、人々がこうした Git リポジトリをそのままクローンして、うまく動くことを期待しているのは本当に怖いです。
  • TOB-BREW-n が複数並んでいるので、このプロジェクト専用の CVE 番号のようなものなのかと思いました。
    追記: ああ、“Trail Of Bits - homeBREW” だったのですね。それでもたぶん合っているように思います。

    • その通りです。監査結果には TOB-$PRODUCT-$XXXX という慣例を使っています。$PRODUCT は監査対象で、$XXXX は各発見事項の一意な増分カウンターです。
      私の知る限り、多くの監査会社が似た方式を使っています。
  • このブログ記事の表現が少し紛らわしいです。Homebrew と一緒にこの監査を行ったとありますが、名前に見覚えがあったので Homebrew README を確認したところ、https://github.com/Homebrew/brew のメンテナー一覧に William Woodruff がいました。
    ブログ記事でこの点に触れていない理由があるのか気になります。大きな違いを生むとは思いませんが、明確にしたいです。

    • 監査を行った当時はメンテナーではありませんでした :-)
      長い間、このプロジェクトの非メンテナー「メンバー」でした。これは、内部の会話やガバナンスに引き続き参加したい元メンテナーに与えられる、準名誉職のような立場です。その後、監査が終わって数か月後、監査計画前には存在も予定もされていなかった Homebrew 関連の別作業がきっかけで、再びメンバーシップを提案されました。
      この内容は、会社と Homebrew メンテナー双方に対して行った利益相反の開示にはすべて含めていましたが、ブログ記事にも明記できるという点には同意します。今日追加してみます。
      要約すると、監査実施時点ではメンテナーではありませんでしたが、以前はメンテナーで、現在もメンテナーです。監査は私と同僚たちが専門業務として実施しました。