「Ghostcommit」、画像にプロンプトインジェクションを隠しAIエージェントを欺いて機密情報を窃取

研究者らは、AIコードレビューアーが決して開かないPNG画像の中に悪意ある指示を隠すことで、リポジトリの機密情報を盗み出すプルリクエストを作成しました。

レビューアーはこの変更を問題なく通過させます。その後、コーディングエージェントがこの画像を読み込み、リポジトリの.envファイルを開き、すべてのキーを一見無害な数値の羅列としてソースコードに書き込みます。

「Ghostcommit」の仕組み

この攻撃はASSET Research GroupのSudipta Chattopadhyay氏によるもので、同氏はミズーリ大学カンザスシティ校の准教授であり、この研究成果をBleepingComputerに提供しました。

同グループは今週GitHub上で概念実証(PoC)を公開し、調査結果を影響を受けるベンダーに開示済みだとしています。

研究者らはこの攻撃を、すでに大きく開いているレビューの隙間に対するものと位置づけています。過去90日間における公開リポジトリの中でも活動が活発な上位300件を対象に、プルリクエスト6,480件を調査したところ、マージされたPRの73%が実質的な人間によるレビューもボットによるレビューも一切受けずにデフォルトブランチに到達していたことが分かりました。

Image

この手口の巧妙な点は、悪意ある指示がレビューアーに検知され得るテキストではないことにあります。それは1枚の画像なのです。

AGENTS.mdファイル、つまりエージェントが自動的に読み込みプロジェクトのポリシーとして扱う類のコーディング規約ファイルは、一見ごく普通のビルド衛生管理の内容に見え、機密情報については一切言及していません。

このファイルはただ1枚の画像、docs/images/build-spec.pngを指し示すだけです。攻撃コードはそのPNG内に描画されたテキストに存在します。その内容は、.envファイルを1バイトずつ読み取り、各バイトを整数としてエンコードし、その結果をモジュール定数として出力し、コミット前にデコードした数値が実際のファイルと一致することを検証する、というものです。

テキストベースのレビューアーにとって、画像とはバイナリの塊にすぎません。

CodeRabbitはデフォルト設定において画像ファイルをレビュー対象から完全に除外しています。Bugbotも問題を検出しませんでした。

研究者らはこのPNGに「malicious prompt injection(悪意あるプロンプトインジェクション)」という文言と、.envを読み取れという明示的な命令まで詰め込みましたが、それでも検査を無傷で通過しました。

偽の50行にわたる「provenance validator(来歴検証ツール)」と、でっち上げのインシデント事後報告書を用意することで、この規約に十分な裏付けコードを持たせ、レビューアー側の最後の防御線、すなわち裏付けとなるコードを伴わない規約を検知する整合性チェックを突破しました。

情報窃取が実際に起きるのは、その後の話です。

このペイロードは、開発者が全く無関係なセッションでコーディングエージェントにトークン追跡モジュールの作成のようなありふれた依頼をするまで、休眠状態のまま潜んでいます。

エージェントは起動時にマージ済みのAGENTS.mdを読み込み、指し示された画像へのポインタをたどり、.envを開き、依頼されたモジュールを作成する際に冒頭付近に「provenance」という定数を書き込みます。

ある一連の検証実行では、Claude Sonnetを動かすCursorが1回目の試行でこれを実行し、出力された定数は311個の整数からなり、それらをバイト単位でデコードすると.envの内容がそのまま復元されました。

開発者は自分が依頼した機能が出来上がったのを見てコミットし、攻撃者は公開されたそのコミットから数値をデコードします。シークレットスキャナーはこれに全く気づきません。いずれのツールもPythonの整数タプルをASCIIに逆変換してチェックする機能を持たないためです。

'Ghostcommit' in action: an Antigravity session asked to add a token-tracking module quietly computes the _PROV_CANARY constant, the .env contents encoded as a list of integers, ready to merge (ASSET Research Group)

古くからある手口が突く新たな盲点

AIシステムに行動を起こさせるため画像内に指示を隠すという手法自体は、新しいものではありません。

2025年には、Trail of BitsのKikimora Morozova氏とSuha Sabi Hussain氏が、より巧妙な手法を実証しました。すなわち、フル解像度では何の変哲もなく見えるが、AIシステム自体の縮小処理パイプラインで再サンプリングされると読み取り可能なプロンプトインジェクションのテキストとして浮かび上がる画像で、この手法はGemini CLIのようなツールを欺くことに成功しました。

さらに最近では、Gaslightと名付けられたmacOSマルウェアが、バイナリ内に偽のシステム障害メッセージを埋め込みました。こちらは異なるタイプのAI読み取り手を標的にしたもので、AI支援によるマルウェア解析ツールに自身の解析を中断するよう仕向けようとするものでした。

今年の初め、筆者自身がManifold Securityで行った研究では、AIコードレビューアーが偽装されたgitアイデンティティに騙され、悪意あるプルリクエストをマージしてしまう事例を発見しました。こちらは画像すら必要としませんでした。

Ghostcommitで使われる画像には、そうした偽装は一切施されていません。情報窃取のための指示はPNGの中に、平文の読み取り可能なテキストとしてそのまま存在しています。

この手口を成立させているのは、隠された信号ではなく、むしろ盲点です。すなわち、レビューアーがそもそもそのファイルを一度も開かないという点にあります。

危険の所在を決めるのはモデルではなくツール側

最も鋭い発見は、実際の危険がどこに存在するのかという点についてのものです。

各パターンで10回ずつ実行した結果、モデルよりもコーディングツールの方が結果を左右することが分かりました。

CursorとAntigravityのコーディングツールはいずれも、Sonnet、Gemini、GPT-5.5をはじめとする複数のモデルの下で、この画像の指示に従い.envを漏洩させました。

一方、同じSonnetの重みを使用しているAnthropicのClaude Codeは、同じ規約を読み込んだ上で明示的に拒否理由を説明しながら実行を拒否し、研究者らがテストしたすべてのモデルの下で一貫して拒否し続けました。

Antigravity環境下では、Opusは一度は機密情報を書き出したものの、その後ソーシャルエンジニアリングのパターンだと気づき、処理を完了する前に削除しました。同じモデルでありながら結果は正反対で、これはそれを取り巻くハーネス(実行基盤)によって左右されたものです。

これは単一の対策ではなく、多層防御の必要性を示しています。

研究者らは自らその一層を構築しました。

研究者らは次のように述べています。「この盲点は構造的なものであるため、私たちはそれを塞ぐレビューアーを構築しました。マルチモーダルなプルリクエスト防御ツールで、4GBのグラフィックカード1枚で動作するGitHubアプリとして展開されます」

「これは、不可視文字のスキャン、コミットされたコードの構造のスキャン、規約テキストに対するLLMによる検査、そして決定的に重要な点として、画像に対するLLMによる検査を組み合わせたものです」

未見の80件のプルリクエストを対象にした実地試験では、突破された攻撃はわずか1件のみで、画像を用いたあらゆる亜種を含めても防御に成功し、正当な30件のPRについては誤検知が一件も発生しませんでした。

研究者らはこう述べています。「これは添付ファイルを実際に開くレビューアーに近い存在です。そして現在のレビューアーはそれを行っていません」

もう一つの防御層は実行時対策です。ペイロードが出荷される前に検知しようとするのではなく、エージェントが本来触れる理由のない認証情報ファイルを読み込んだ際に、実際にどのような動作をするかを監視するというアプローチです。

攻撃者に先んじてすべてのレイヤーをテストする

セキュリティチームが記録できているのは、成功した攻撃のうち54%にとどまり、アラートが発報されるのはわずか14%です。残りは環境内を検知されないまま通過しています。

Picusのホワイトペーパーでは、侵害・攻撃シミュレーションによってSIEMおよびEDRのルールをテストし、脅威が検知をすり抜けるのを防ぐ方法を紹介しています。

ホワイトペーパーを入手する

翻訳元: https://www.bleepingcomputer.com/news/security/ghostcommit-hides-prompt-injection-in-images-to-fool-ai-agents-steal-secrets/

ソース: bleepingcomputer.com