三つのエージェント、盗む物はひとつ
Black Hat USA 2026 で Novee は、Claude Code・Gemini CLI・Codex のデフォルト構成を三通りの方法で破った。いずれも、匿名の第三者が立てられる GitHub の issue が起点だった。バイパス自体は無関係 — 引用符の解釈のずれ、強制されないシェル許可リスト、信頼される AGENTS.md — だが、三つのチェーンはすべて同じ一歩で終わる。エージェント自身のプロセスから本物の認証情報を読み取る、という一歩だ。Bromure Agentic Coding はその最後の一歩を固めない。プロセスを空にする。持ち出しは成功し、囮が送られる。
三つのベンダー、互いに無関係な三つのハーネスのバグ、そして共通する最後の
一手 — エージェントのプロセスに置かれた API キーやトークンを読み取り、
外へ送り出す。Bromure のプロファイルでは、その値は brm_… の
プレースホルダだ。持ち出しは成功するが、攻撃者が受け取るのは、あなたの
Mac の外では何の意味も持たない文字列である。
今週の Black Hat USA 2026 で、Novee は 「Trusted Enough to Run: Breaking AI Agents in Official Workflows」を発表 した。リサーチャーの Elad Meged は、三つのコーディングエージェントの デフォルト構成を各ベンダー自身の公開リポジトリに対してテストし、三つ すべてを破った。解説記事は 8月6日 に公開された。
侵入口はどのケースでも同じで、しかも最も安上がりなものだった。権限ゼロの 匿名の第三者が立てた GitHub の issue やプルリクエストである。エージェント は作業の一環としてその信頼できないテキストを読み、ハーネス — モデルの 周囲にあって何を実行してよいかを決めるコード — は、そのテキストを境界線の 向こう側に留めることに失敗する。Novee はテスト対象の三ベンダー以外にも、 百を超える公開リポジトリ で同じ脆弱なデフォルトを見つけている。
三つの侵入経路には互いに何の関係もない。だが行き着く先は同じで、その 共通の終着点こそが持ち帰るべき教訓である。
三つの異なる扉、同じ突き当たりの壁
Claude Code
CVE-2026-54316 が割り当てられたチェーンは、二つの継ぎ目を突いた。ひとつ目
は、Claude Code がコマンドを検証する方法と、シェルが実際にそれを解釈する
方法のずれである。バリデータには無害に見えた引用符付きの文字列が、bash の
手に渡ると別様にパースされ、git push --receive-pack フラグは
二十三の安全チェック
— どれも個々には正しく仕事をしていた — をすり抜けた。ふたつ目の継ぎ目は
持ち出しである。読み取り専用の tac — ファイルを逆順に表示するコマンド —
だけで秘密を読み取り、逆さまにしたまま GitHub Actions のログ経由で外へ
押し出せたし、別の変種は HuggingFace モデルの公開ダウンロードカウンタを
突いては読み返すことで、API キーを一文字ずつ漏らした。Anthropic は修正を
出荷した。
Gemini CLI
CVSS 10.0 と評価された。ヘッドレスモードの Gemini CLI はワークスペースの
フォルダを自動的に信頼し、そこにあるエージェント設定を何であれ読み込んだ
— サンドボックスも承認もなしに。そのため、設定ファイルを仕込んだプルリク
エストは、サンドボックスが初期化される前に実行された。ハーネスの前提が
二つ崩れた。「制限付き」のシェル許可リストは実行時に一度も強制されて
おらず、子プロセスから秘密を消し去る環境のサニタイズは、親プロセスには
それを残したままにしていた — /proc 経由で読める状態で。Google は
0.39.1 と 0.40.0-preview.3 でヘッドレスの信頼モデルに破壊的変更を
出荷した。
Codex
Codex は共有ワークスペース上でエージェントを二パス走らせる。.git と
.codex は書き込みから保護されていたが、AGENTS.md はそうではなく、
しかも実行のたびに信頼された指示として再読み込みされていた。信頼できない
入力を処理する第一パスが汚染された AGENTS.md を書き込み、「安全な」第二
パスがそれを権威として読み込んで、悪意ある指示を昇格した権限のまま引き
継いだ。OpenAI は三日以内に二つのパスを分離されたジョブに切り分けた。
変わらない部分
Novee 自身の総括は、「これらはどれも単純な設定ミスではなく、受け渡しの 接点で崩れた、正しいセキュリティ判断だった」というものだ。ハーネスに ついての読みとしてはそれが正しい。だが、各チェーンがどこで終わるかを 見てほしい。
Claude の tac は認証情報を読み取り、HuggingFace のカウンタは API キー
を漏らす。Gemini の /proc の穴は親プロセスの秘密を晒す。Codex の昇格
した第二パスは環境のトークンを攻撃者の支配下にある指示へと運ぶ。無関係
な三つの継ぎ目が三通りに開き、そのどれもが最後には同じ対象へ手を伸ばす。
エージェントのプロセスや環境に置かれ、読まれるのを待っていた本物の秘密
である。
これこそ、これらのエクスプロイトすべてが共有する前提だ — エージェントと
してコードを実行できれば、認証情報はすぐそこにある、という前提である。
そして実際、ほぼ常にそこにある。ANTHROPIC_API_KEY、GITHUB_TOKEN、AWS
のキー。コーディングエージェントを動かす普通のやり方は、それらすべてを
プロセスの環境に置く。ツールがそこにあることを期待しているからだ。
Bromure Agentic Coding はハーネスの軍拡競争に勝とうとはしない。ハーネスが 守っているものを、そもそも取り除く。
鎖が断ち切られる場所
Bromure は各プロファイルのエージェントを Apple Silicon 上の使い捨て Linux VM の中で実行し、そのネットワークトラフィックの全バイトを、 エージェントの走る箱の外にあるホスト上のプロキシ に通す。Novee が攻撃したのと同じ自律的な issue トリアージエージェントを、 ワークフローランナーに預ける代わりに自分でホストして動かせる。この構成に 対して三つのチェーンをなぞれば、どれもほどけていく。そして認証情報の 一歩は、三つとも同じ形でほどける。
認証情報は決してプロセスの中にない
共通の最後の一歩を無効化するのが、この保証だ。Anthropic・OpenAI・xAI
の本物のキーは brm_… プレースホルダとして VM に注入され、本物の値に
差し替えられるのはホストのプロキシ上、通信路上で、それぞれのキーが
属するただ一つの宛先ホストに対してだけである。キーは VM のメモリにも
/proc にも、子や親のプロセスが読める環境変数にも、ログにも決して
存在しない。tac が読むのは囮。HuggingFace のカウンタが一文字ずつ
漏らすのも囮。/proc を浚っても返るのは囮。講演にあったどの持ち出し
も最後まで実行され、ちょうど一台の Mac でしか意味を持たない文字列を
送り出す — そしてその Mac は、実行が行われたマシンではない。
RCE は消去できる箱に着地する
「エージェントを実行しているホスト上でのコード実行」— これは Gemini の アドバイザリの言い回しであり、そのホストこそ Bromure が動かす信頼境界 である。Gemini のサンドボックス初期化前の実行も、Claude のシェル バイパスも、手に入るのは使い捨ての Linux VM だ。macOS からハイパー バイザ一枚を隔て、NAT の内側にあり、あなたのネットワーク上のものには 何も到達できない。Erase home は実行が書き込んだものを破棄し、 ホームディレクトリをクローン直後の状態に戻す。エージェントを乗っ取った エクスプロイトが手に入れるのは、どのみち捨てるつもりだった VM である。
main への書き込みはプロキシで拒否される
二つの権限昇格が狙う獲物は同じだ。Claude のチェーンは
git push --receive-pack でプッシュし、Gemini のチェーンは悪意ある
コードを main ブランチに押し込む。これはサプライチェーン側の半分で、
汚染されたチェックアウトは下流で毒入りパッケージになる。GitHub の
ガードレールを読み取り専用か破壊的操作ブロックに設定すれば、
git-receive-pack はホストのプロキシで拒否される。VM 内で回避された
ガードには発言権がない場所だ。フェッチは通り続けるが、ブランチを汚染
するはずのプッシュは通らない。
指示ファイルは、従う前に採点される
侵入口はハーネスが封じ込め損ねた信頼できない issue や PR のテキストで
あり、Codex のチェーン全体は書き込まれた AGENTS.md の中に生きて
いる。Bromure はエージェントが読むツール結果の内容 — ウェブページ、
issue 本文、ファイル内容 — をローカルのプロンプトインジェクション
モデルで採点し、さらに権威ファイルそのもの(CLAUDE.md、AGENTS.md
とその変種)を専用の分類器と不可視 Unicode ペイロードのスキャナで
採点する。Codex の二つのパスの間にある汚染された AGENTS.md は、
まさにこの二つ目の検出器が捕まえるために作られたものであり、モデルが
そのファイルに基づいて行動する前に、ホスト上で走る。
これらの設定のうち二つはデフォルトで有効であり、認証情報ブローカーに 至っては設定ですらない — それは Bromure のプロファイルが秘密を保持する、 そのやり方そのものである。裏口のチャネルも締めくくられている。GitHub Actions のログも、HuggingFace のカウンタも、想定外の外向きホストも、 すべてホストのプロキシを通過し、Security Log と Trace Inspector が全 リクエストのホスト・ステータス・差し替えレポートを記録する。囮を漏らした サイドチャネルは、あなたが読めるリストの一行でもあるのだ。
ハーネスはこれからも破られる
Novee が促した三つの修正はどれも良いもので、そしてどれも幅が狭い。 Anthropic は引用符解釈のずれを直し、Google はヘッドレスの信頼モデルを 変え、OpenAI はパスを分離した。それぞれ、見つかった特定の継ぎ目を閉じて いる。だが、三つのエクスプロイトに共通していたもの — 使える認証情報が エージェントのプロセスに置かれ、取られるのを待っていたこと — を変える 修正はひとつもない。次のハーネスのバグは — Novee は他の百のリポジトリで 同じデフォルトを見つけているのだから、次は必ず来る — また同じものへ手を 伸ばすだろう。
個々の開示にはパッチと設定の見直しで応えられるし、そうすべきだ。だが パッチが閉じるのは一つのエージェントの一つの扉であり、見直しはリポジトリ ごと、リリースごとの作業になる。動くエクスプロイトが手を伸ばす認証情報 は、三つのエージェントでも、将来のどのバグでも同じものだ。そしてそれは、 たった一つの決断で手の届かない場所へ移せる唯一のものでもある。本物の秘密 はホストに置き、エージェントにはプレースホルダを渡し、本物の値は宛先の ホストに対してだけプロキシに生成させる。
Bromure Agentic Coding をインストールして、失っても 構わない箱を — そして認証情報を — エージェントに与えてほしい。