- セキュリティ研究チームが CodeRabbitの本番サーバーでリモートコード実行(RCE) および APIトークン・機密情報の漏えい に成功
- Rubocopを利用したPRにより環境変数を窃取し、PostgreSQLへのアクセスと100万件のリポジトリの読み書きが可能 だった
- GitHub Appのプライベートキー の漏えいにより、公開/非公開リポジトリを含む大規模な保存領域へのマルウェア注入、ソースコード改変など実害が生じうる状態だった
- CodeRabbit側は 脆弱性報告から数時間以内に即時対応 し、セキュリティ対策を強化した
- 外部ツール実行時にはサンドボックス分離・最小権限・ネットワーク遮断などで セキュリティ事故を防ぐ 必要性が強調される
紹介
- 2025年1月、Kudelski Security研究チームがCodeRabbitの深刻なセキュリティ脆弱性を公開
- PRレビュー自動化ツールとして広く使われるCodeRabbitで、remote code execution(RCE)、環境変数および機密情報の漏えい、100万件を超えるリポジトリへのRead/Write権限の確保 という重大な問題が確認された
- この記事はBlack Hat USAで発表された公開脆弱性の詳細分析を扱っており、コードレビュー型ツールと連携システムの脆弱性の実例 として参考価値が高い
- 報告された脆弱性は申告直後に迅速にパッチ適用された
CodeRabbitの概要
- CodeRabbitはGitHub/GitLab Marketplaceで 最も多くインストールされているAIベースのコードレビューアプリ
- 両プラットフォームで 100万件のリポジトリと500万件のpull request をレビューしている
- ユーザーがPRを作成または更新するたびに、AIエンジンがコードを分析してコメントと提案を自動生成する
- コード要約、セキュリティ脆弱性検出、改善点の提示、ダイアグラム生成など 開発生産性 の向上効果が大きい
CodeRabbitの利用と権限構造
- Proプランはlinter・SAST(静的解析)ツール連携機能を提供する
- GitHubアカウント認証およびアプリインストール時に 選択したリポジトリへの読み書き権限 を付与することになる
- この権限管理が悪用された場合、インストールされたすべてのリポジトリのコードに 直接的な影響 を与えうる
外部ツール実行とエクスプロイトの発見
- CodeRabbitはPR内のコード変更を検知すると 複数の外部静的解析ツール(例: Rubocop) を自動実行する
- Rubocopは
.rubocop.yml 設定ファイルを使って 外部Ruby拡張ファイル(ext.rbなど) をロードできるよう設計されている
- 攻撃者は
.rubocop.yml と ext.rb に悪意あるコードを挿入してPRを提出し、CodeRabbitがリモートサーバー上でそのコードを実行するよう誘導できた
- この手法で実行されたコードは サーバー上のすべての環境変数を攻撃者のサーバーへ送信 した
環境変数漏えい内容の分析
- 漏えいした環境変数には、次のような 多様なサービスのAPIキー、トークン、パスワード などが含まれていた
- Anthropic/OpenAI APIキー、Encryption salt/password、GitHub Appプライベートキー、PostgreSQL接続情報など
- RCEを通じてデータベースアクセス、コード改変、サービス内部情報漏えいなど 二次被害が大きく波及性も高い
- 本番サーバー上でさらに悪意ある探索を進めることも可能だったが、サービス運用を考慮して最小限の確認にとどめて中断した
100万件のリポジトリRead/Write権限の獲得
- 環境変数に含まれていた GITHUB_APP_PEM_FILE(プライベートキー) を使ってGitHub APIへ認証可能
- CodeRabbitがアクセス可能なすべてのリポジトリ(公開/非公開を含む)に対して
- ソースコードの読み書き、リリースファイルの差し替え(サプライチェーン攻撃)、git履歴の変更など非常に強力な権限を行使できた
- 再現コード(PoC) が公開され、実際に悪用可能であることが証明された
PoC要約
- PyGitHubなどのライブラリを使い、漏えいしたプライベートキー、App IDなどで 任意のリポジトリアクセストークンを発行
- このトークンを通じて、非公開リポジトリの複製、ファイル変更、新規コミット、リリースファイル改ざんなどを自動化できる
CodeRabbit社内/非公開リポジトリ侵害の可能性
- CodeRabbit組織自身も自社サービスに導入して利用していたため、CodeRabbitの内部ソースコードリポジトリへのアクセスおよび複製 も可能だった
- 組織名さえ分かれば、インストールIDを照会してすぐにそのリポジトリ一覧へアクセスすることが可能だった
影響の要約
- 非公開リポジトリへの不正アクセス・個人情報漏えい
- ソースコード改ざん、マルウェア/バックドア挿入など サプライチェーン攻撃 の脅威
- GitHub Actionsなど追加脆弱性との連鎖の可能性
- 直接的なRCEによるデータ破壊、サービス停止、他サービスへの連鎖被害の発生
文脈とAI判断の限界
- 攻撃中であってもPR自体はCodeRabbitによって正常にレビューされ、脆弱性警告コメントは残したものの実際には脅威となる構文を識別できなかった
- 「AIコードレビューツール」が実際の危険状況の文脈まで把握できるわけではないことを示している
対応と推奨事項
- CodeRabbitは 脆弱性報告から数時間以内にRubocopを無効化し、機密情報の差し替え、システム監査を実施 した
- サンドボックス未適用のツール(Rubocop)で問題が発生し、対応後は すべての外部ツールを隔離環境で実行 するよう改善した
- セキュリティ強化のため、外部ツール実行環境における環境変数の最小化、ネットワークアクセスIP制限、インターネットアクセス遮断など 防御的設計の必要性 が強調される
責任ある公開と結論
- 2025年1月、報告後に迅速な対応と措置が行われた
- PoCにとどまったものの、悪意ある攻撃者であれば高価値リポジトリの選別、大規模ランサムウェア、破壊的サプライチェーン攻撃などに容易に悪用しうることが確認された
- 外部解析ツール・AIベース自動化サービスとの連携時には、サンドボックスと最小権限の原則 を実装する重要性が再確認された
1件のコメント
Hacker Newsの意見
うわ、これは本当に深刻な脆弱性だ。今回修正されたのは幸いだが、そもそも最初にこんな問題があったこと自体が問題だ。クラウドプラットフォームでユーザーコードを解析するシステムを作る際の最も基本的なルールは、解析器を必ず隔離された環境で実行することだ。プラグインを通じて直接コード注入が起こりうるし、linter/解析器/コンパイラは複雑なソフトウェアであるため、脆弱性の攻撃面が広い。任意のリポジトリに対してこうしたツールを共有環境で実行することが危険ではないと仮定しては絶対にいけないと思う。自分もコード解析プラットフォームを運営していたが、顧客リポジトリで自社開発の解析器を回す場合でも、サンドボックス環境で動くように設計していた。環境変数やネットワークリクエスト権限も含めていなかったが、それでも解析はサンドボックス内でのみ実行された。これがコード解析を安全に行う唯一の方法だ
https://github.com/getgrit/gritql
Coderabbitの有料サブスクリプションを解約した。企業が問題を認めるために、HNでバイラルになるほど広まらないといけない状況が常に心配だ。公式ブログのどこにも今回の脆弱性への言及がなく、今日も新しい投稿はない。ミスは誰にでもあると思うが、こういうことが起きたときに透明性を持って公開しない点が企業イメージを損なうと思う
「エクスプロイトが実行されている最中に、CodeRabbit自身がPRに危険警告コメントを残していたが、実際にはそのPRを実行しながらハッキングされていた」という点が本当に奇妙だ。AIが自分がハッキングされていると語る世界に生きている現実に、妙な違和感を覚える。また、CodeRabbitチームが素早く対応したのはよかったが、「他の業者は調査連絡にもまったく返答せず、今もなお脆弱だ」という点のほうがさらに心配だ。CodeRabbitチームには拍手を送りたいが、みんな慎重に動くべきだ
CEOの公式声明の一部で「Rubocopがサンドボックス環境の外で動いていたのが問題だった」とあるが、正直ちょっと疑わしい。なぜ特定の一つだけが完全に違う動作をしていて、それがたまたま突破されたジョブだったのか?
本当に興味深い記事だったが、実は驚くようなことでもない。ユーザーが何も考えずに権限の広いアプリを大量に追加し、GitHubの権限システム自体にも問題があるので、こういうことは必然的に起こるしかなかった。多くの人がGitHubアプリにリポジトリ書き込み権限やクラウド権限まで過剰に許可している。ブランチ保護があっても、pull request経由でGitHub Actionsに特権アクセスできてしまう。きちんと設定するにはGitHub OIDC audienceを修正しなければならず、文書化も十分ではない。アプリ開発元に権限を減らし、一部機能を無効化した別バージョンを作ってくれと頼んでも、たいてい関心を示さず、セキュリティ上の問題を理解していない。GitHubではアプリのアクセス権をもっと細分化できるようにすべきだし、全体として権限そのものをもっと細かく分けるべきだ
本当に衝撃的だ。まだ記事を読み終えてもいないのに、情報量が多すぎて頭がくらくらする。ハッカーが10万〜100万規模のオープンソースツール/ライブラリ/ソフトウェア配布物にマルウェアを仕込めたかもしれないという部分では、世界が終わっていてもおかしくなかったとさえ思う。今後どれだけ多くの類似問題が残っているのか想像するのも難しい
こうした深刻なセキュリティ失敗は「侵害事故」または「インシデント」と分類し、報道を通じて義務的に公開させるべきだと思う。7,000余りの顧客、100万個のリポジトリにアクセスできるツールが、せいぜい11歳児でも作れそうな単純なエクスプロイトで破られたということだ。これほど簡単なハッキングなら、botやブラックハット、APTなどがすでに侵入して密かに居座っていた可能性が高い。ホワイトハットが公開する前から入り込んでいたなら、脆弱性パッチは新たな攻撃者を防ぐだけで、すでに潜伏している存在は排除できないかもしれない。セキュリティが難しいのは分かるが、本当に気を引き締めるべきだと言いたい
問題の一つは、各種コード解析器、バンドラ、コンパイラ(例: Rustコンパイラなど)が何の警告もなく任意コードを実行できてしまう点だ。たとえば、ハッカーが採用課題だと言ってリポジトリを送りつけ、私が「npm install」やRustのコンパイルコマンドを実行しただけで、自分のコンピュータが即座にハッカーの手に落ちる可能性がある。あるいは会社の同僚一人のPCがハッキングされてマルウェアがリポジトリに入れば、最終的にはグローバル大企業全体が外国のハッカーに制圧されることすらありうる。こうした構造を作ったのはnpmとRustコンパイラだ。こうしたツールは、外部コマンドを実行するたびに明示的な確認を求めるべきだ(許可済みコマンドの一覧をキャッシュして毎回尋ねないようにはできる)。Linuxもまた、開発者が簡単に使える安全なサンドボックスを提供すべきだが、今は一つひとつ自分で作るしかない。しかも、JSパッケージのインストールなど、場合によっては外部コード実行が不要な作業もある。そして環境変数に秘密情報や設定を入れるのは本当に悪い方法だ。「12-factor app」を作った人は、コマンドラインスイッチや設定ファイルというものを知らないように見える
「好きなようにGitHubアプリになれる」権限の鍵(プライベートキー)が環境変数に保存されていたのは、本当に最悪の慣行だ。誰でもハッキングされうるとはいえ、これは秘密管理の最も基本中の基本だ。GitHub公式ドキュメントにも、環境変数にプライベートキーを入れるなとはっきり書かれている。本当に基礎中の基礎だ
https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps#storing-private-keys
Rubocopの設定ファイルで拡張Rubyファイルのパスを指定できるという記述を読んだ瞬間、「まさかユーザー拡張ツールを本番環境で直接動かしていたのか……」と思ったが、案の定そうだった。もちろん、こうした穴を一つ塞いだだけで十分安全になるわけではない。大半のlinterは攻撃的な入力に対して監査やファジングが行われていること自体まれだろうし、これはただドアを開け放って「ハッキングしてください!」というネオンサインを灯していたようなものだ