そのノートブックは自前の MCP サーバーを連れてきた
CVE-2026-75149 は marimo のコードインジェクションだ。ノートブックは一つの Python ファイルであり、そのファイルは自分の設定をコメントブロックの中に抱えていて、バージョン 0.23.15 まではその設定が MCP サーバーを宣言できた。編集モードで開くだけで、marimo は攻撃者のコマンドをサブプロセスとして起動する。セルは一つも走っていない。残りはパッチが語っている。ダウンロードした文書が、しかもオペレーター自身の設定より高い優先度で設定できていた環境まわりのカテゴリを、まるごと五つ落としたのだ。Bromure Agentic Coding では、エージェントが起動してよいプログラムの一覧はホスト側のパネルであり、起動時に VM へ書き込まれ、ワークスペースの中の何もそこに追加できない。
リポジトリがコーディングエージェントを設定し直せる。それは前から知って いた。変わったのは、それをやれるものの大きさだ。いまやそれは、Slack で 転送されてきて、中身を見ようと開くだけの一つのファイルである。
誰かがノートブックを送ってくる。marimo のノートブックなので、base64 の出力が
詰まった JSON の塊ではなく、ごく普通の .py ファイルだ。人がこの形式を好む
理由のほとんどはそこにある。読めるし、差分が取れるし、出力を剥がす
pre-commit フックなしで git に入れられる。
だから読んでみて、問題なさそうなので、セルをいじろうと編集モードで開く。
サブプロセスが立ち上がる。セルはまだ一つも実行していない。これはファイルが 自分から要求したことであり、ノートブックの読み込みが終わる前に起きている。
それが CVE-2026-75149 だ。 8 月 19 日に公開され、今週 The Hacker News が取り上げた。CVSS 8.7、CWE-94、Gregory Tan のクレジット、marimo 0.23.15 で 修正済み。VulnCheck のアドバイザリ は仕組みを一行にまとめている。ノートブックに細工された MCP サーバー エントリが入っていて、編集モードで開くとそのエントリのコマンドがローカルの サブプロセスとして起動される。
設定はコメントの中にあった
marimo のノートブックは
PEP 723、つまりインラインのスクリプト
メタデータのための Python の慣習を使って、自分の設定を持ち歩く。ファイル先頭の
コメントブロックの中に住む小さな TOML テーブルで、スクリプトが隣にプロジェクト
ファイルを置かずに依存関係と Python のバージョンを宣言できるように存在して
いる。uv はこれを読む。marimo も読み、ノートブック設定のための
tool.marimo テーブルで拡張している。
このテーブルの二つの性質が損害を生んだ。そしてそのどちらも、単体ではバグでは ない。
一つめは、marimo がノートブックのメタデータを最も高い優先度で、つまり marimo を実行している人が設定した内容の上にマージしていたことだ。整形の好みに ついてなら、それが正しい既定値である。二スペースのインデントを望むノート ブックは、あなたのグローバル設定に勝つべきだ。ファイルがどう見えるべきかを 知っているのは著者であって、あなたではない。
二つめは、そのマージがほとんど無濾過だったことだ。修正前、marimo のサニタイザ
がノートブック由来の設定から取り除いていたのはちょうど一つの鍵、
tool.marimo.runtime.auto_instantiate だけだった。tool.marimo の他はすべて
通り抜けた。tool.marimo.mcp も含めてだ。そこは Model Context Protocol の
サーバーを列挙する場所であり、MCP サーバーの一覧とは起動するコマンドの一覧の
ことである。
この二つを合わせると、ダウンロードしたファイルの先頭のコメントがプログラムを 指名し、marimo にそれを起動させられた。ここにエクスプロイトは一つもない。 ファイルは設計されたとおりに機能を使っただけであり、その設計は、ファイルを 書いたのはあなた自身だと前提していた。
パッチこそが開示だ
修正の PR #10281 は 「additional pep 723 sanitization」という題で、拒否リストを許可リストに 入れ替えている。ノートブック由来の設定は、いまや見た目とエディタまわりの セクションに限られる。整形、保存、表示、キーマップ、診断、lint、スニペット、 データソース、言語サーバー、共有、venv、ランタイム、パッケージ管理。
落とされたセクションのほうが面白い半分だ。ai、mcp、completion、
secrets、server。
五つの鍵ではなく、五つのセクションまるごとである。そしてダウンロードした文書は
そのすべてを設定できた。PR の根拠はもう一つのペイロードにも触れている。
そちらはサブプロセスすら要らない。ai セクションは API のベース URL を持つ
ので、ノートブックはモデルのエンドポイントを自分の選んだホストへ向け直せた。
メンテナの言葉では「オペレーターの API キーを攻撃者が制御するエンドポイントへ
持ち出すことを可能にしかねない」。
この攻撃のベース URL 版は 7 月に扱った。
リポジトリが ANTHROPIC_BASE_URL を設定できて、
Claude Code がリポジトリの選んだ宛先へ自分の鍵を送ってしまった件だ。この
カテゴリで最も安上がりな攻撃である。コードは一行も走らず、送信するのは被害者
自身のクライアントだからだ。marimo 版は、その配送手段をリポジトリから
コメントへと縮めた。
信頼の単位は小さくなり続ける
このバグの系譜は短い。そしてその歴史の中で、攻撃者があなたのマシンに必要と するものは毎回少なくなっている。
4 月、Wiz Research が Amazon Q Developer の
CVE-2026-12957
を報告した。CVSS 8.5、5 月に修正、6 月に公表。Amazon Q は開いたワークスペース
から .amazonq/mcp.json を読み、そこで定義されたサーバーを起動していた。
それらのプロセスは開発者の環境をまるごと引き継いだ。AWS の鍵、クラウド CLI の
トークン、API のシークレット、SSH エージェントのソケット。Amazon の修正は、
信頼できないワークスペースから MCP サーバーを起動する前に確認を挟むことだった。
8 月には ChainDrop が
歩き回ったリポジトリにエージェント設定をコミットしていた。
.claude/settings.json の SessionStart フックと、.vscode/tasks.json の
folderOpen タスク。プロジェクトをクローンして開くだけで足りた。
そのどちらもリポジトリを必要とした。誰かがプロジェクトを公開するか乗っ取るか しなければならず、あなたはそれをクローンしなければならず、ドットファイルの ディレクトリはツリーの中に居座っていて、疑り深い人間なら覗くことができた。
marimo が必要とするのはファイルだ。一つのファイル。文書として表示され、文書が 届くやり方で届く。Slack のスレッド、メールの添付、朝会で誰かが貼った gist、 Kaggle からのダウンロード。ノートブックはクローンしない。開く。開くことこそ、 それが何なのかを知る方法だからだ。
mcp ブロックはこの十八か月で開発者ツールのほとんどに広がった。そして
そのブロックは、人から人へ渡り歩くファイルの中に住んでいる。リポジトリの
ルート、エディタのディレクトリ、そしていまや文書のメタデータ。どれもが、
あなたのマシンの何かが起動する気でいるプログラムの一覧であり、書いたのは
最後にそのファイルを触った誰かだ。レジストリのスキャナはそれを読まないし、
ロックファイルはそれを覆わないし、コメントに適用できる来歴の証明を提案した者は
まだいない。
プロファイルにおける MCP サーバーの出どころ
Bromure Agentic Coding は、来歴の問いに答えられる場所で 答える。ホスト上で、VM が起動する前にだ。
各プロファイルの設定には、Agents、Credentials、Guardrails、Supply Chain と 並んで MCP パネルがある。そこにサーバーの一覧が入る。各エントリは個別に オンオフでき、二つのトランスポートのどちらかを使う。HTTP はオプションの ベアラートークン付きのリモート URL、stdio は VM の中で起動されるローカル コマンドだ。Bromure はその一覧を、動いているエージェントが期待する形式に 変換し——Claude Code なら JSON、Codex なら TOML——起動時に VM へ注入する。
いまの一文の進行方向を読んでほしい。設定はホストからゲストへ、 起動時に、あなたが設定パネルで保守している一覧から流れ込む。あとから ワークスペースに現れたファイルは、MCP サーバーの出どころではない。だから 優先度を取り違えるマージは存在しないし、セクションが増え続ける設定スキーマと 同期を保ち続けるサニタイザも要らない。文書は、届かない一覧にエントリを 足すことはできない。
それでもノートブックを開いてみる
以上のどれも、バグのあるバージョンを動かしている当日には助けにならない。 だから 0.23.15 より前の marimo を持ち出し、攻撃者に勝ちを譲り、敵対的な ノートブックをプロファイルに通してみよう。
サブプロセスは他人のコンピュータの中で始まる。 Bromure Agentic Coding の
セッション作業は、プロファイルの Ubuntu VM の中の kitty タブで行われる。
macOS からはハイパーバイザ一枚を隔てた場所だ。marimo edit はそこで走り、
コメントの中のコマンドもそこで走る。Resources → Storage ではプロファイルは
三層だ。プロファイルごとの /home/ubuntu には Erase home… があり、
ワークスペースのシステムディスクには共有イメージから再クローンする
Reset to base… があり、その下にはゲストの何一つ触れられない読み取り専用の
ベース OS がある。メニュー項目一つで、そのエントリが入れたものは消える。
引き継ぐ環境は囮の束だ。 Amazon Q のバグが痛かったのは、起動されたサーバー
が開発者の本物のシェルの子であり、本物の資格情報を引き継いだからだ。Bromure の
プロファイルでは、それらの変数名の後ろには何もない。汎用の API キーは VM へ
エクスポートされた brm_… のプレースホルダーであり、外へ出る途中でホストの
プロキシが本物の値へ差し替える。kubeconfig は合成物で、使い捨てのクライアント
証明書が入っている。AWS のリクエストはホスト側で署名し直されるので、プロキシを
迂回したプロセスが得るのはアクセスではなく InvalidSignatureException だ。
~/.docker/config.json には偽の base64 の塊が入っている。SSH の秘密鍵は
そもそも VM の中に存在しない。
ホストがプロファイルごとのエージェント経由で署名するからだ。ある資格情報に
Require approval to use を有効にすれば、差し替えのたびにホスト側のダイアログ
になり、許可には期限が付く。五分、一時間、セッションの残り。
ベース URL の手口が集めるのはプレースホルダーだ。 プロキシが本物の資格情報
を差し込むのは、その資格情報自身のホスト宛の外向きリクエストに対してだけだ。
AI のエンドポイントを attacker.example へ向け直したノートブックが集めるのは、
VM の環境に置かれているもの、つまり何も開けない brm_… という文字列である。
サーバーはネットワークに届かなければならない。 攻撃者にとって有用な何かを
起動する MCP エントリには、後続の段階を取ってくるにせよ見つけたものを送り返す
にせよ、外向き通信が要る。Guardrails → Outbound connections は pf 風の
ルールテーブルだ。アクション、プロトコル(tcp、udp、web、any)、ホスト
または CIDR、ポートの一覧、そして web なら HTTP メソッドの一覧。上から下へ
評価し、最初に一致したものが勝つ。加えて Unmatched traffic を Allow か Deny
で選ぶ。Deny にして、仕事に必要なホストを並べれば、そのエントリの宛先は一覧に
ない。テーブルはホスト側の仮想スイッチとプロキシで強制されるので、ゲストが
自分のルーティングに何をしようと答えは変わらない。
そもそもファイルが VM の中になければならない。 プロファイルが共有する Mac
のフォルダは最大八つで、どれも Folders パネルで手ずから選び、
/home/ubuntu/<basename> にマウントされる。~/Downloads に落ちてきた
ノートブックは、あなたが置くまでプロファイルの中にはないし、あなたの Mac の
残りは、そのノートブックが起動したものからディレクトリを一歩たどった先には
ない。
そして、起きたことは見える。 Security Log ウィンドウ(Window → Security Log…)はホスト側の単一の時系列テーブルだ。パッケージの判定、 ファイアウォールの決定、資格情報の差し替え、プロンプトインジェクションの検出。 ゲストのコードはそれを編集できない。ゲストのコードはそこへ届かないからだ。 あなたが起動していないプロセスからの外向き接続がブロックされれば、それは一行 として現れる。六週間後にクラウドの請求書で知るよりましだ。
有効にする
marimo を 0.23.15 以降へ更新すること。あそこの許可リストは良いパッチだ。
そのうえで、あなたのツールが mcp ブロックを読んでいる他のすべての場所を
見に行き、そのファイルを書けるのは誰かを問うこと。
プロファイルの中で二分の価値がある設定は、いつもと同じ短い一覧だ。 Guardrails → Outbound connections、Unmatched traffic を Deny にして、 仕事に必要なホストの許可リストを添える。Credentials → Require approval to use を、金を使えるものやデータを消せるものすべてに。Supply Chain → OSV vulnerability check、鍵があるなら socket.dev や Delpi のフィルタも、 既定で有効な二日間の年齢ゲートの上に重ねて。Prompt Injection → CLAUDE.md と AGENTS.md のスキャナ。あなたのエージェントに対する権威を主張するファイルを、 まさにそういうものとして扱う。
ノートブックはこれからも転送され続けるし、設定フォーマットはこれからも セクションを増やし続ける。どちらも有用だからだ。あなたが変えられるのは、 文書がプログラムの起動を求めたとき、聞いているのがどのマシンかということだ。 Bromure Agentic Coding を導入し、サーバーの一覧は プロファイルエディタに置き、次の親切なコメントブロックには、メニューから 消せる VM を設定させておけばいい。