すべての投稿に戻る
公開日 · 著者 Renaud Deraison

サンドボックスがポートを開けた

CVE-2026-65105 は NVIDIA NemoClaw のネットワークのバグだ。AI エージェントをサンドボックスの中で走らせること、それがこのツールの存在理由そのものである。サンドボックスは Docker コンテナで、コンテナはホストのループバックに届かない。そこで NemoClaw はローカルのモデルサーバーを全インターフェースで起動した — ウェブページがそこへ話しかけるのを止めていた唯一のチェックが、それで切れた。訪れたページが持ち去ったのはモデルのチャットテンプレート、モデルが読む前にすべてのシステムプロンプトを組み立てる層である。Bromure Agentic Coding では、ローカルエンジンはループバックの、ゲストが決して知らないポートで待ち受け、ゲストはネットワークではなく vsock 経由でそこへ届く。

穴を開けたのは、封じ込めそのものだった。あなたのマシンのループバックに届 かないサンドボックスは、モデルサーバーを全インターフェースへ押し出す。そ うなればブラウザのタブからも届く。

あなたはコーディングエージェントを慎重なやり方で走らせている。エージェントは サンドボックスの中に住んでいる。それが考えるのに使うモデルは自分のマシンで動 いているから、プロンプトは建物の外へ出ない。誰もが勧める二つのことを、あなた はやってのけた。

そしてブラウザのタブを開く。その瞬間から、あなたのエージェントは欠陥を仕込ん だコードを書きはじめる。しかもその欠陥について、口をつぐんだままで。

これが CVE-2026-65105 だ。8月25日に Oasis Security の Elad Luz と Ofek Itach が公表した。彼らの レポート はこれをドライブバイのエージェント乗っ取りと呼ぶ。公表前に NVIDIA の PSIRT へ持ち込んでおり、同じ日に The Hacker NewsSiliconANGLECSO Online が記事にした。NVIDIA は アドバイザリ とパッチを出している。

製品は NemoClaw、OpenClaw エージェントを OpenShell サンドボックスの中へ、推論 用のローカル Ollama バックエンドとともに展開するための NVIDIA のツールだ。封 じ込めが売り文句である。

コンテナはループバックに届かなかった

Ollama はポート 11434 で待ち受け、デフォルトでは 127.0.0.1 にバインドする。 ループバックインターフェース、そのマシン自身からしか届かない場所だ。

OpenShell のサンドボックスは Docker コンテナである。コンテナは自分のネットワ ーク名前空間を持つので、コンテナの中の 127.0.0.1 はコンテナであってホストで はない。したがってサンドボックスの中のエージェントは、ホストのループバックに バインドされたモデルサーバーに届かない。

NemoClaw はこれを環境変数ひとつで解決した。OLLAMA_HOST=0.0.0.0:11434 を付け て Ollama を起動する。マシンのあらゆるインターフェース、オフィスの wifi に面 した一枚も含めて、である。ソケットが世界に応答している間も、インストーラーは Using Ollama on localhost:11434 と表示し続けていた。

そして、設定上の選択を脆弱性へ変える一歩が来る。Ollama の API には認証がなく、 代わりに二つのガードを持っている。一つ目は Origin ヘッダーに対する CORS チ ェック。二つ目は Host ヘッダーの許可リストで、localhost、マシン自身のホス ト名、そして .localhost.local.internal で終わる名前を受け入れる。

二つ目のガードには例外がある。Ollama は自分がバインドされているアドレスを見て、 そのアドレスがループバックでなければ、Host チェックを丸ごと飛ばす。 なぜ誰 かがそう書いたのかは分かる。公開インターフェースにバインドする運用者はリモート のクライアントを迎えたいのであり、ループバック用に作られた Host 許可リストは その全員を追い返してしまう。結果として、ポートを晒す設定が、そのポートを守るチ ェックを解除する設定と同じものになった。

残るのは CORS チェックだが、DNS リバインディングは構造上 CORS を素通りする。攻 撃者は自分が支配するドメインからページを配り、ポートは 11434、そのうえでそのド メインを 127.0.0.1 に再解決させる。OriginHost はいまや攻撃者が選んだ 同一のホスト名であり、Ollama はそれを同一オリジンと読む。 リバインディングの仕組みは先週詳しく扱った ので前提としよう。あなたが訪れたページが、あなたのマシン上のサービスのクライア ントになる。所要は一分ほどだ。

リバインディングは面白い侵入経路である。同時に難しいほうの経路でもある。 0.0.0.0 のサーバーは、ブラウザの小細工など一切なしに、同じネットワークセグメ ントの他のすべての機器へ応答する。来客のノート PC、スマートテレビ、二つ隣の席 の乗っ取られたマシン。

制約OpenShell サンドボックス = Docker コンテナ独自のネットワーク名前空間を持つので127.0.0.1 = コンテナ、ホストではないエージェントはモデルサーバーに届かない本物の問題で、本物の答えが要ったNemoClaw が出した答えOLLAMA_HOST=0.0.0.0:11434全インターフェース、認証なし表示は「Using Ollama on localhost」Ollama の二つのガード1 · Origin ヘッダーの CORS チェック2 · Host 許可リスト: localhost、ホスト名、.localhost .local .internalバインドが非ループバックなら 2 は飛ばされる入り口は二つページ: ドメインを 127.0.0.1 へ再束縛しOrigin と Host が一致、CORS を通過LAN: 小細工なしで直接ポートを叩くどちらも無認証で API 全体に届くポートを晒した設定は、そのポートを守るチェックを切った設定と同じものだった。
ポートが動いた理由。サンドボックスは Docker コンテナなのでホストのループバックに届かず、NemoClaw はモデルサーバーを全インターフェースにバインドしてそれを解決した。Ollama はバインドアドレスがループバックでないとき Host ヘッダーのチェックを飛ばすので、残るのは CORS チェックだけ — そして DNS リバインディングは Origin と Host を攻撃者が選んだ同じ名前にしてしまう。

彼らはコード実行を狙わなかった

API に届くのは退屈なほうの半分だ。届いたあとに Oasis がやったことが、新しい部 分である。

分かりやすい一手は、悪意あるシステムプロンプトをモデルに書き込むことだ。ここで はそれが失敗する。OpenClaw はリクエストのたびに自前のシステムプロンプトを messages 配列で送り、クライアントのプロンプトがモデルに保存されたものに勝つ。 そこで研究者たちは一層下へ降りた。

Ollama の /api/create エンドポイントは template フィールドを受け付ける。 チャットテンプレートとは、構造化された messages 配列 — ロール、内容、ツール定 義 — を、モデルが実際に読む一続きの平文ブロックへ変換する Go テンプレートだ。推 論時に、クライアントがメッセージを渡し終えたあとに走り、そのすべてに触れる。

攻撃はリクエスト三本である。/api/show で本物のテンプレートを読む。ツールの描 画と特殊トークンはそのまま一字も変えず、システムメッセージの描かれ方だけを 変えて、好きな指示を末尾に足す。/api/create で書き戻す。

クライアントは相変わらず自分の丁寧なシステムプロンプトを送る。テンプレートは毎 回そのプロンプトを攻撃者のもので包み、モデルがその最初のトークンを見る前に済ま せてしまう。CSO Online が引く Elad Luz の言葉では、その指示は「ガードレールや運 用者に見えるどんなものよりも一層下」に座る。

書き換えはディスク上のモデル定義に落ちるので、会話にもリセットにも再起動にも生 き延びる。モデルのメタデータ、サイズ、表示される能力はそのままで、インストール 済みモデルの一覧で見た目は何も変わらない。そのモデルを使う者すべてがそれを受け 取る。手で叩く CLI も、あなたが昼食に出ている間に走るエージェントもだ。

Oasis はそうした指示が何に使えるかを列挙している。どれも、気づかれるほど派手で はない。

バグを織り込む

微妙な欠陥を含んだコードを出す。レビューで読み流せる種類のもの — レビュー で読み流されるように書かれているのだから。

黙っている

セキュリティ上の懸念を決して指摘しない。以前は警告してくれたエージェントが 警告しなくなったことに気づくのは難しい。

選択を誘導する

特定のパッケージ、特定の URL、特定の設定を勧める。あなたは提案を求め、提案 を受け取った。

家へ送り返す

エージェントにネットワークがあるなら、会話の中身とファイルの中身を攻撃者の 選んだエンドポイントへ送り出す。

無認証 API の残りは脇役だ。/api/generate/api/chat で他人の GPU で推論を 回し、/api/pull でディスクを埋め、/api/delete でモデルを壊し、/api/push で被害者の ollama.com アカウントとして公開し、/api/me でいま降り立った相手の ホスト名、公開鍵、ログイン中のユーザー名を知る。

サンドボックスは最初から爆心地ではなかった

Oasis はサンドボックスが何をして何をしなかったかについて慎重だ。OpenShell のサ ンドボックスは機能している。ファイルシステム、ネットワーク、プロセスを隔離し、 端末をきれいに保つ。組織の中のエージェントは、ソース管理、CI/CD、内部 API、ク ラウドアカウント、チャット、そして山ほどの MCP サーバーを握ることで存在価値を稼 ぐ。エージェントを奪えば、そのアクセスを操れる。レポート自身のまとめによれば、 真の爆心地はエージェントが到達を許された資源に従うのであって、サンドボックスの 境界に従うのではない。

それはコンテナがあなたのために決して答えてくれない問い であり、ここではひねりが付く。露出を作ったのは、封じ込めの層そのものだった。 Docker のネットワーク名前空間は仕事をした。それを迂回したことが、モデルサーバー を wifi の上に置いた。

プロファイルの中でローカルモデルはどこに住むか

Bromure Agentic Coding もローカル推論を走らせる。プロファイ ルのエージェントは、クラウドのプロバイダーではなく端末上のモデルへ向けられる。 NemoClaw が提供しているのと同じ機能だ。その下の配管は逆向きに組まれていて、その 一歩一歩が、上で述べた何かへの直接の答えになっている。

エンジンはループバックにバインドし、0.0.0.0 には決してしない。 端末上のモ デルサーバーは Mac の 127.0.0.1 で、固定番号ではなく起動時にカーネルが配るポー トで動く。動的ポートは退屈な理由でそこにある。その Mac で伝統的な 11434 をすでに 握っている何か — Ollama も LM Studio も含めて — と Bromure が争わないためだ。同 時にそれは、ページが狙える well-known なポートが存在しないことを意味する。

ゲストはネットワーク経由でそこへ届かない。 VM の中で、エージェントは自分が期 待するアドレス 127.0.0.1:11434 を叩く。その接続はルーティングの近くを通らない。 VM 内のブリッジが TCP ストリームを vsock — virtio のソケット転送 — のポート 8446 へ継ぎ、チャネルのホスト側がそれをループバックのエンジンへ渡す。vsock チャ ネルはハイパーバイザーと一台のゲストのあいだのパイプである。IP アドレスもホスト 名も DNS レコードも持たないので、再束縛するものがなく、スキャンするものがなく、 ブラウザが叩く方法もない。ゲストはエンジンがどのポートにいるかを決して知らない。

あなたの LAN からは何一つ VM に届かない。 Resources → Network の既定モードは NAT だ。外向きは通り、ローカルネットワークからは何も VM に届かない。これは NemoClaw の発見のうち、リバインディングを一切必要としない半分 — 同じ wifi の機器 が直接ポートを叩く経路 — を閉じる。しかもあなたが設定を変えずに閉じる。

書き換えるべきモデル定義が VM の中に存在しない。 ゲストのエージェントは bromure-local という単一のモデル識別子に固定され、bromure.llm という、裏に DNS レコードのない合成ホスト名でそれを呼ぶ。VM 内のプロキシがその名前を捕まえ、 ホストへ転送する。どのモデルが答えるかはホスト側であなたが持つ対応表であり、プ ロファイルの Local Models パネルにある。変更はホスト側の張り替えで済む。VM の中の再設定もエージェントの再起動もいらない。テンプレートも重みもルーティング も、すべて Mac の上にある。ゲストの中に /api/create に当たるものはない。ゲス トの中にモデルがないからだ。

ローカル推論はクラウドと同じパイプラインを通る。 その通信はポートへ直行せず Bromure のプロキシを通るので、Anthropic や OpenAI への呼び出しと同じ扱いを受け る。同じトレース、同じロギング、同じプロンプトインジェクション検知だ。Prompt Injection パネルは、エージェントが読むファイルの中身、ウェブページ、ツール出力を ローカルの PromptGuard モデルで採点し、権威として読み込む CLAUDE.md、AGENTS.md、 GROK.md を、ファインチューンした ModernBERT 分類器と、不可視 Unicode ペイロード 向けの決定的スキャナーで採点する。検知は Security Log へ送られるか、リクエストを 一時停止するか、そっけない 451 を返す。三つの応答のどれを選んだかによる。

全インターフェースのポートエンジンはどこで待ち受ける?0.0.0.0:11434 · 固定、周知サンドボックスはどう届く?IP で。wifi の他の全員と同じようにほかに誰が届く?再束縛するページと LAN、無認証で誰がテンプレートを書き換えられる?ポートに届くものすべてが、次でPOST /api/createアドレスを持たないチャネルエンジンはどこで待ち受ける?127.0.0.1:<カーネル割当> · ホストのみVM はどう届く?vsock 8446 — 網ではなくパイプほかに誰が届く?誰も。IP もホスト名も DNS もない誰がモデルを選ぶ?あなたが、Local Models パネルでゲストは bromure-local の名しか知らない
エージェントにローカルモデルを与える二つのやり方。左は全インターフェースの HTTP ポート、認証なし、その背後に書き換え可能なモデル定義 — ネットワーク上のどの機器からも、ホスト名を再束縛するどのページからも届く。右はカーネルが割り当てたポートのループバックエンジンで、叩くアドレスを持たない vsock チャネル経由でゲストから届き、モデルの選択はホストが持つ。

では、モデルが嘘をついていると考えてみる

アーキテクチャの主張を十分に押し進めれば、誰かがそれを試すべきだ。ならば好きな 経路で攻撃者に勝ちを渡そう。毒入りテンプレートでも、モデル提供者の悪い一日でも、 すり抜けたプロンプトインジェクションでもいい。あなたのエージェントはいまや他人の ために働き、それでも出力は上手に読める。あの四つのペイロードをプロファイルに通し てみる。

選択を誘導しても、選択はやはり審査される。 このペイロードはモデルの権威に最 も強く寄りかかり、そして最も壁にぶつかる。Bromure はパッケージの取得を、エージェ ントが応答を見る前にホストのプロキシで評価する。npm、PyPI、Cargo、RubyGems、 Maven、NuGet、Go modules、Packagist にわたって、である。そしてプロキシは、誰がそ のパッケージを勧めたかを尋ねない。二日間の経過日数ゲートが既定で有効で、公開した ばかりのタイポスクワットに必要なものの大半はこれで片づく。OSV 照会を入れ、パッケ ージフィルタリングを socket.dev か Delpi に向け、インストールスクリプトを剥がせ ば、推薦はモデルに発言権のない四つの意見を生き延びなければならない。VM の中の .npmrcpip.conf はこれらの設定を締めることはできる。緩めることはできない。

家へ送り返す。ただし線はあなたのものだ。 持ち出しには外向き通信が要る。 Guardrails → Outbound connections は pf 風のルール表だ。アクション、プロトコ ル (tcpudpwebany)、ホストまたは CIDR、ポートの並び、そして web には HTTP メソッドの並び。上から順に照合し、最初に一致したものが勝つ。 Unmatched traffic は Allow か Deny。Deny にして、仕事に必要なホストを並べれ ば、攻撃者のエンドポイントはその中にない。強制はホスト側の仮想スイッチと SNI 層 で行われるので、ゲストが自分のルーティングに何をしようと判定は変わらない。

バグを織り込み、そして出荷しようとする。 Guardrails はエージェントが到達でき る各サービスにモードも持たせている。GitHub、GitLab、Bitbucket、AWS、Kubernetes、 DigitalOcean、コンテナレジストリ、設定済みの各データベースエンドポイントについて Block destructiveRead-only だ。読み取り専用モードでは git push は書 き込みに分類されて止まる。fetch は常に通る。バックドア入りのコミットは VM に留ま る。

そして受け継ぐアクセスは偽物だ。 Oasis の爆心地の指摘こそ、プロファイルが最 も労力を注いでいる箇所である。VM の中の資格情報は囮だ。環境変数としての brm_… というプレースホルダー、使い捨てのクライアント証明書を入れた合成の ~/.kube/config~/.docker/config.json の中の偽の base64 ブロブ、そしてホスト で署名し直される AWS リクエスト。プロキシを迂回したものはアクセスではなく InvalidSignatureException を受け取る。SSH の秘密鍵は そもそも VM の中に一度もない — ホスト がプロファイルごとのエージェント経由で署名する。ある資格情報について Require approval to use を入れれば、置き換えのたびにホスト側のダイアログが出て、時間の 区切られた許可になる。五分、一時間、セッションの残り。フォルダー共有は手で選んだ 八つのディレクトリが上限なので、Mac の残りはそもそも読まれる場所にない。

そのすべてが見える。 Security Log ウィンドウ (Window → Security Log…) は ホスト側の単一の時系列テーブルだ。パッケージの判定、VM が開いた宛先のすべてと許 否、資格情報の差し替え、インジェクション検知。ゲストのコードはそれを編集できない。 ゲストのコードはそこへ届かないからだ。一日が終わったら、Resources → Storage の Erase home…Reset to base… がプロファイルをクローン直後の状態へ戻す。

有効にする

NemoClaw を使っているなら NVIDIA のパッチを当てること。Ollama をループバックへ戻 し、正当に外へ出る必要があるものの前にトークン付きのプロキシを置く。The Hacker News は Windows と WSL の経路がこのリリースで完全には覆われていないと注記してい るので、思い込まずに自分のプラットフォームをアドバイザリで確かめてほしい。そのう えで、マシンの上にあるほかのモデルサーバーを全部見つけ出し、どのアドレスにバイン ドしているかを尋ねよう。答えは人が思うより 0.0.0.0 であることが多い。コンテナ がそれを求め続けるからだ。

プロファイルで二分の価値がある設定は、いつもの短いリストだ。Guardrails → Outbound connectionsUnmatched traffic を Deny に。Credentials → Require approval to use を、金を使えるものとデータを消せるものに。Supply Chain → OSV vulnerability check と、鍵があるなら socket.dev か Delpi のフィル タリングを、既に有効な経過日数ゲートの上に。Prompt Injection → 検知器を両方。ロ ーカルモデルへの通信も、クラウドへの通信と同じ注意深さで読まれるように。

モデルは自分のマシンで走らせ続けてよい。その選択はプロンプトがローカルに留まると いう価値を買うし、それは持つに値する。だがその選択は、それを抱えるサーバーに他の 誰が話しかけてよいのかについては何も言わない。それはソケットについての問いであり、 ソケットには、コンテナのご機嫌を取るために設定された環境変数よりましな答えがふさ わしい。Bromure Agentic Coding を導入し、モデルはホストで選び、 ゲストにはポートではなくパイプを残そう。