1 ポイント 投稿者 GN⁺ 12 시간 전 | 1件のコメント | WhatsAppで共有
  • git push 経路の内部プロトコル欠陥だけでバックエンド上でリモートコード実行が可能であり、GitHub.com はすでに緩和済みだが、GHES にはパッチ適用が必要
  • ユーザー制御入力である push option がそのまま X-Stat ヘッダーに入り、セミコロン 1 つで新しいフィールドを注入でき、同じキーの後続値が先行値を上書きする last-write-wins の挙動が悪用された
  • 注入可能なフィールドのうち rails_envcustom_hooks_dirrepo_pre_receive_hooks を組み合わせるとサンドボックスを回避し、攻撃者が指定したパスのフックを git ユーザー権限で実行できた
  • 同じメカニズムで GitHub.com の enterprise mode フラグ まで注入でき、shared storage node でコード実行が確認され、そのノード上の他ユーザーや組織のリポジトリまで読み取れる状態につながった
  • 異なるサービスが共有フォーマットを信頼する マルチサービスアーキテクチャ では、入力サニタイズ不備、非本番実行経路、パス検証漏れが組み合わさると重大な脆弱性に発展しうることを示している

即時対応と影響範囲

  • GitHub.com ではこの問題はすでに緩和済みで、追加対応は不要
  • GitHub Enterprise Server は即時対応が必要で、CVE-2026-3854 の修正を含む GHES 3.19.3 以降 へアップグレードする必要がある
  • 脆弱なバージョン範囲は GHES 3.19.1 以下 で、修正版として 3.14.24, 3.15.19, 3.16.15, 3.17.12, 3.18.6, 3.19.3 が提示されている
  • 執筆時点で GHES インスタンスの 88% がまだ脆弱な状態だった
  • GitHub の追加技術情報と復旧手順は GitHub Security Blog で確認できる
  • Wiz の顧客は Wiz Threat Center の事前構築済みクエリ により脆弱な GHES インスタンス を特定できる

調査の背景とアプローチ

  • GitHub の内部 git インフラは、すべての git push を処理する経路であり、複数の内部サービスが異なるプログラミング言語で書かれている
  • このような マルチサービス構造 では、各コンポーネントが共有データをどのようにパースし信頼するかの差異が脆弱性につながりうる
  • これまでは、このパイプラインを構成する大量の コンパイル済みブラックボックスバイナリ を抽出して監査するには、過大な時間と手作業が必要だった
  • AI 強化ツールIDA MCP ベースの自動リバースエンジニアリングにより、コンパイル済みバイナリを迅速に解析し、内部プロトコルを再構成できた
  • その過程で、ユーザー入力がパイプライン全体を通じてサーバー動作に影響する箇所を体系的に追跡し、入力フロー全体の 根本的欠陥 を突き止めた

内部アーキテクチャと信頼境界

  • git push が SSH で入ると、リクエストは babeldgitauthgitrpcd、そして pre-receive hook の順に流れる
  • babeld はすべての git 操作の入口として SSH 接続を受け取り、認証は gitauth に渡す
  • gitauth はユーザー資格情報とリポジトリへの push 権限を確認し、ファイルサイズ制限やブランチ名ルールなどのセキュリティポリシーを返す
  • babeld はこの応答に基づいて、セキュリティメタデータ を含む内部 X-Stat ヘッダーを構成する
  • gitrpcdX-Stat ヘッダーを受け取って後続プロセス環境を設定し、独自の認証なしに babeld を全面的に信頼している
  • pre-receive hook は push を受け入れる前に、ファイルサイズ制限、ブランチ名ルール、LFS 整合性、管理者定義のカスタムフックを検査する
  • 中核となる結合点は、; 区切りの key=value ペアを含む X-Stat ヘッダー だった
  • 内部サービスは X-Stat; 基準で分割してマップに格納し、同じキーが 2 回出ると後続値が先行値を上書きする last-write-wins ルールに従う
  • babeldgit push -o で渡された push optionspush_option_0, push_option_1, push_option_count のようなフィールドとして X-Stat に一緒に入れる

脆弱性の原因: X-Stat フィールド注入

  • babeld はユーザー制御入力である push option 値X-Stat ヘッダーにコピーする際、セミコロンをサニタイズしていなかった
  • ;X-Stat のフィールド区切り文字であるため、push option 内のセミコロン 1 つで本来のフィールドを抜け出し、攻撃者制御フィールド を新たに作成できた
  • たとえば push_option_0 内に large_blob_rejection_enabled=bool:false を注入すると、先に設定されていた bool:true が後続値で上書きされる
  • この挙動はバイナリ解析と実際の GHES インスタンスでの パケットキャプチャ の両方で確認された
  • リバースエンジニアリングと wire-level 解析を組み合わせ、注入可能な X-Stat フィールドをマッピングした
  • 特にセキュリティ上重要なフィールドとして rails_env, custom_hooks_dir, repo_pre_receive_hooks, large_blob_rejection_enabled, reject_sha_like_refs, user_operator_mode が確認された
  • このうち rails_envcustom_hooks_dirrepo_pre_receive_hooks の 3 フィールドがリモートコード実行につながる核心だった

GHES で RCE に至る経路

  • GHES は push を受け入れる前に実行される custom pre-receive hooks をサポートしている
  • pre-receive バイナリには、X-Statrails_env 値だけで分岐する 2 つの実行経路 があった
  • 値が production ならフックをサンドボックス内で実行し、それ以外の値ならサンドボックスや隔離なしで git サービスユーザー権限のまま直接実行する
  • したがって rails_env に非本番値を注入すると、サンドボックス回避 が可能になる
  • 続いて custom_hooks_dir を注入すると、フックスクリプトを探す既定ディレクトリを攻撃者が制御できるようになる
  • 最後に repo_pre_receive_hooks にパストラバーサルを含むフック定義を注入すると、バイナリのパス解決が攻撃者制御ディレクトリとトラバーサルペイロードを結合し、ファイルシステム上の任意パス を指すようになる
  • 非本番実行経路は、このように解決されたパスを引数なし、サンドボックスなし、git サービスユーザーとして直接実行する
  • 実際の検証では git push 1 回で uid=500(git) の出力が返り、git ユーザー権限での RCE が確認された
  • この権限により、GHES インスタンスのファイルシステム読み書きと内部サービス設定の可視性を含む 全面的な制御権 を取得できた

GitHub.com への拡張とクロステナント露出

  • 同じエクスプロイトチェーンを GitHub.com リポジトリに適用した当初は、push 自体は成功したが custom hooks は実行されなかった
  • user_operator_mode=bool:true を注入して両プラットフォームのデバッグ出力を比較した結果、GitHub.com では custom hooks のコード経路に到達していないことが分かった
  • 追加のリバースエンジニアリングにより、サーバーの enterprise mode 動作有無を制御するブールフラグが X-Stat ヘッダーに存在することが確認された
  • GHES ではこのフラグが既定で true のため custom hooks 経路が常に有効であり、GitHub.com では既定値が false のため通常状態ではその経路に到達しない
  • このフラグも同じメカニズムで注入できたため、フィールドを 1 つ追加注入することで GitHub.com でも完全な エクスプロイトチェーン が機能した
  • その後、GitHub.com インフラ内部で hostname 実行結果が返され、GitHub.com RCE が確認された
  • GitHub.com は マルチテナントプラットフォーム であり、複数ユーザーや組織のリポジトリが共有バックエンドインフラに保存されている
  • コード実行が発生した場所は shared storage node で、ここで git ユーザーはそのノード上のすべてのリポジトリ操作を処理するための広範なファイルシステム権限を持つ
  • このユーザーが侵害されると、そのノード上の他組織や他ユーザーのリポジトリも、所有者に関係なく読み取れるようになる
  • 侵害された 2 つのノードでアクセス可能なリポジトリのインデックスエントリを列挙したところ、各ノードに 数百万件のエントリ があり、他ユーザーや他組織のリポジトリが含まれていた
  • 他テナントの実際のリポジトリ内容にはアクセスせず、自身のテストアカウントのみを用いて、git ユーザーのファイルシステム権限が ノード内のすべてのリポジトリ読み取り を許していることを検証した

主要な教訓と公開日程

  • git push 1 回だけでも、内部プロトコル欠陥を悪用してバックエンドインフラ上で リモートコード実行 が可能だった
  • 異なる言語で書かれた複数サービスが共有内部プロトコルでデータをやり取りする場合、各サービスの 信頼前提 そのものが攻撃面になる
  • 今回のチェーンでは、あるサービスが push option 値をそのまま挿入し、別のサービスが X-Stat の全フィールドを信頼し、pre-receive hook は本番環境で rails_envproduction であると仮定していた
  • 本番バイナリ内の 非本番コード経路、フックスクリプトに対するパストラバーサル検証の欠如、区切り文字ベースのプロトコルにおける入力サニタイズ不備は、他のコードベースにも現れうるパターンである
  • マルチサービスアーキテクチャを運用するチームは、とりわけセキュリティセンシティブな設定が共有データフォーマットから導出される場合、ユーザー制御入力が 内部プロトコル に沿ってどう流れるかを点検する必要がある
  • 今回の研究では、IDA MCP を含む AI 強化リバースエンジニアリング ツールが、コンパイル済みバイナリ解析と内部プロトコル再構成を迅速に可能にした
  • こうしたツールが成熟するほど、深い クロスコンポーネント解析 を必要とする脆弱性群を見つける上で、より重要な役割を果たすとみられる
  • 公開日程としては、2026-03-04 に X-Stat push option 注入脆弱性を発見し、同日 GHES 3.19.1 で RCE を確認して GitHub に報告、GitHub.com 修正も同日にデプロイされた
  • 2026-03-10 には CVE-2026-3854CVSS 8.7 が割り当てられ、GHES パッチが公開された
  • 2026-04-28公開 された

1件のコメント

 
Hacker Newsの反応
  • 内部の認証サービスが設定するセキュリティ上重要なヘッダーに、
    エンドユーザーがgit push -oで入れた任意の文字列まで一緒に入るようになっていたわけだ
    後からなら何とでも言えるとはいえ、これはさすがにひどすぎる

  • AI支援リバースエンジニアリングというやり方は、今のLLMエージェントの強みをよく示している
    コードを大量に学習したモデルなら、複雑なシステム内部を理解する速度を大幅に引き上げられる
    セキュリティ研究はたいてい 1) 複雑な内部動作を把握することと 2) その中で脆弱性を見つけることが重なっていて、
    ときには本当の内部メカニズムさえ見えれば、脆弱性そのものは案外すぐ見えることもある
    CVE-2026-3854は、内部を知ってもすぐ obvious な類型ではなかったが、
    もっと伝統的だったり近づきやすい攻撃面に露出していたなら、このコマンドインジェクションはすぐ発見されていただろうと思う

    • もともとAIはC++リバースエンジニアリングや、C++を単純なCへ大量に移植するのが得意だという兆しがあった
      ただ最近はその流れが少し乱れたか、あるいはC++の文法の複雑さから生まれる dev/vendor lock-in を守りたい側によって意図的に妨げられているようにも感じる
  • Wizで働いている人がいるのかと思うくらい、成果物はかなり良さそうに見える
    製品も極端な成長と機能肥大を経験しながら、まだかなりよく持ちこたえているし、
    セキュリティチームも本当に面白いものをよく見つけてくる

    • Unit 8200出身者が多い
    • ノイズが多すぎるので、うちは critical だけを見るために osv-scannertrivy を回すカスタムパイプラインしか使っていない
    • そこにいるわけではないが、うちの会社で使ってみると完全に無害な行動にもやたら警告を出す
      なのにCLIでDCを照会して資格情報をリセットするような、少し怪しい作業には静かなままで拍子抜けする
  • babeldがpushリクエストを転送するとき、内部リクエストのX-Statヘッダーにpush optionsを入れていて、
    その値はユーザーがgit push -oで入れる任意の文字列
    ところがセミコロンを sanitize しないまま値をそのままコピーしたため、
    ;がX-Statフィールドの区切り文字なので、本来のフィールドから抜け出して攻撃者が新しいフィールドを作れてしまった
    本当に最も単純なミスをそのままやってしまったレベルで、木の実が低すぎて地中に埋まっているくらいに見える

    • ああ、Bobby Tablesの母親は本当に賢かった
  • まだ悪用される前に見つかった脆弱性なのに、
    BREAKINGunauthorized accessmillions of repositoriesのような表現でいたずらに恐怖を煽る必要があるのかと思う
    https://x.com/wiz_io/status/2049153209982140718

    • とはいえ、それらの表現が不正確というわけでもない
      GitHubは国家支援の攻撃者ではなく、Wizのファジングに引っかかっただけなので運が良かったとも言える
  • **GHESインスタンスの88%**が、7週間前に出た致命的なセキュリティパッチをまだ適用していないというのは、かなり深刻に見える
    https://docs.github.com/en/enterprise-server@3.19/admin/release-notes#3.19.3

    • GHESは事実上、ここ数年ほとんど放置状態に近い
      パッチレベルのリリースを1つ適用するだけでも数時間のダウンタイムが必要で、
      サポートされたHAアップグレード方法もないため、真面目な顧客でさえ最新バージョンにすぐ追随しにくい
      不満を言うとみんな GitHub Enterprise Cloud に移れと言うが、
      今の時代にそれをすんなり選ぶ人がどれだけいるかも疑問だ
      とはいえGHESには、github.comの日々の障害では止まらないという利点はある
    • オンプレミスの顧客のかなりの部分はVPNの背後にGHESを置いていて、
      運用影響の少ない日程を確保してアップグレードしようとしているのだろう
      ただし公開インスタンスなら直ちに更新すべきだ
      記事に出ている情報と公開されているGitHub Enterpriseのソースだけでも、再現手順を組み立てるのは難しくなさそうだ
    • エンタープライズでは定期予定外で更新して全部壊し、その責任を負うことにもなり得るし、
      予定通りに進めて何も起きないことを祈ることもできるが、たいていは後者が選ばれる
    • セキュリティを非常に重視するという理由で github.com を使えない環境では、
      オンプレミス製品が年1回しか更新されなくても不思議ではない
    • 大規模導入環境では、アップグレード工程がどれほど脆いかが核心だ
      データ規模の大きいエンタープライズソフトウェアは、些細なことで導入環境が壊れて運用チームがロールバックするのが珍しくなかった
      昔のSharePointアップグレードは、ほとんどサイコロを振るようなものだった
  • 今回もWizの大きな成果であり、
    AIツールがREや侵入経路の発見をどれほど後押しするかを示す転換点のように感じる

    • だからソースを公開しない方がAIに破られにくいという主張にもひびが入る
      セキュリティは結局、security through obscurityに頼るべきではないというデータポイントがまた1つ積み上がったわけだ
  • みんなGitHubを代替しようと言うが、では何を使うのかという悩みが残る
    GitHubほどのところでさえ今になってRCEが出るのだから、他の代替がもっと良いと簡単には断言しにくい

    • 心配無用、Thomas Dohmkeが新プロジェクトですべて解決してくれる、という冗談もできる
      https://news.ycombinator.com/item?id=46961345
      https://news.ycombinator.com/item?id=47712656
    • まだ現実的な答えは、self-hosted Forgejoを原本フォージとして置き、
      GitHubは無料CIを使っている間だけミラーとして活用するやり方だろう
      シークレットは別の secret-hosting provider に任せればいい
    • うちは6か月前にGitHubからForgejo self-hostedへ移行したが、とても順調だ
      Forgejoがここまで反応が速く、GitHubがここまで遅くなったというのが今でも信じられない
    • 内部向けプロジェクトと外部公開用プロジェクトを、今でははっきり分けている
      内部向けはprivateなForgejoインスタンスに置き、公開用はGitHubに載せつつForgejoへミラーしている
      Forgejoは実質シングルバイナリで設定も簡単なので驚いたし、
      内部サービスはすべてForgejoを見るようにしてあるので、GitHubを離れることになっても摩擦が少ない
    • VPNの背後でself-hostedのGitLabも十分ありだ
      オールインワンのDockerイメージとGitLab runnerが数個あれば、小規模から中規模のチームには十分で、
      本当に必要でなければKubernetes版まで複雑にする理由はない
  • ソースコードからAIが脆弱性を見つけるのも印象的だったが、
    バイナリ実行ファイルからまでやってのけるのは本当に驚きだ
    良い意味でも悪い意味でも潜在力は非常に大きい
    そしてまたしても、データを命令として扱ってはいけないという教訓が示された
    ユーザー入力はすべて sanitize しなければならない

    • Transformerはもともと翻訳のために設計された構造だ
      だから source-to-source や text-to-source に強いのはおなじみの話で、
      asm版を理解するのにも適しているのは、そこまで意外なことではないのかもしれない
      それでも印象的であることに変わりはない
  • これが実際に悪用されたかどうかを判定できるのか気になる

    • 私の見るところ、この脆弱性は匿名ユーザーでも悪用可能だったように見える
      HTTP/git protocol のログで悪用の有無自体はある程度確認できるだろうが、
      実際に何へアクセスし、誰が行ったかまでは残っていない可能性が高い
      エクスプロイトがgitサーバー上で独立実行できたなら、定義上ロギングを回避できたはずだからだ