Maru@maru
Dev Hub

WebMCPセキュリティガイド — ブラウザエージェントの権限乱用を防ぐ方法
Web Model Context Protocol(WebMCP)は、GoogleとMicrosoftが共同提案したブラウザ標準であり、Chrome 149からオリジントライアルが開始されました。従来のエージェントのように画面のスクリーンショットやDOMツリーを複雑にスクレイピングする方式とは異なり、Webアプリが直接構造化されたツールをエージェントに公開することで、迅速かつ安定したインタラクションをサポートします。
しかし、WebMCPツールはユーザーの現在のブラウザセッションとログインクッキーをそのまま共有して実行されます。もしエージェントが外部の悪意あるメールやレビューを読み込み、間接的なプロンプトインジェクションにさらされた場合、ユーザーの権限を悪用してアカウントを削除したり、無断で決済を行うといった「代理人混同問題(Confused Deputy Problem)」が発生する可能性があります。
HTTPレスポンスヘッダーによる一次防衛線:オリジン分離と権限ポリシーの設定
Webエージェントがブラウザ内で安全に動作するために、WebMCPの重要な防衛策はHTTPレスポンスヘッダーを通じて厳格なオリジン分離と権限ポリシーを確立することから始まります。ブラウザがWebページをレンダリングする際、サーバーが適切なセキュリティヘッダーを提供しなければ、悪意あるスクリプトや隣接ドメインからの悪意あるアクセスにさらされる可能性があります。特に、ユーザーのログインセッションと権限をそのまま共有するエージェント環境の特性上、この段階での遮断が不可欠です。
具体的には Origin-Agent-Cluster: ?1 ヘッダーを明示して、同一オリジンのみのための専用プロセス分離をブラウザに要求する必要があります。Chromium Issue TrackerのIssue 521181015によると、明示的な分離がない環境でサブドメイン間で document.domain を緩和して使用する場合、他のオリジンが被害オリジンのWebMCPツールコンテキストを奪取し、任意のツールを登録して実行するというセキュリティ上の脆弱性が発生する可能性があります。これを完全に防ぐには、ページ単位で独立したオリジンエージェントクラスターを割り当てるように設定する必要があります。
さらに、WebMCP専用の権限ポリシーである Permissions-Policy: tools=(self) を適用する必要があります。このポリシーは、サブiframeなどの信頼できない外部リソースが勝手にツールを登録することをブロックします。決済や認証など、エージェントが決して介入してはならない機密性の高いパスには tools=() を指定し、WebMCPの動作自体を根本から封じ込める戦略が有効です。
Fastifyバックエンドでこれらのセキュリティヘッダーを便利かつ安全に制御するには、以下のようにレスポンス送信段階でヘッダーを動的に注入するフックを活用できます。
クライアントサイドの安全ヒントと注釈メタデータ
ブラウザエージェントが悪意あるデータに汚染され、意図しない動作を行うことを防ぐには、クライアント側のツール登録段階から明確な安全ヒントを提供する必要があります。Chrome 150から導入されたドキュメント範囲APIである document.modelContext.registerTool を使用すると、メタデータ注釈を通じてエージェントに詳細な権限制御ガイドを伝えることができます。特にユーザーレビューや外部のWeb検索結果のように、検証されていない外部入力値を扱うツールには untrustedContentHint: true を宣言し、エージェントがこのデータを実行指示ではなく純粋なテキストデータとしてのみ扱うように制御する必要があります。
単純な照会目的のツールには readOnlyHint: true を宣言することで、無分別なユーザー承認ウィンドウが表示されることによるユーザー体験の低下を防ぐことができます。反対に、データの削除や決済といった不可逆的な書き込みツールには consequentialHint: true を注入し、ブラウザレベルで必ずユーザーの明示的な確認手順を経るように設計する必要があります。また、セキュリティ事故を予防するため、ツール説明は最大500文字、パラメータ説明は150文字以内に厳格に制限し、説明フィールド自体を迂回経路として利用するプロンプトインジェクションの試みを根本的に遮断すべきです。
安全にツールを登録するクライアントJavaScriptの実装例は以下の通りです。
このようにツールのライフサイクルを柔軟に制御できる AbortController 信号と主要な安全性ヒントを組み合わせることで、異常な呼び出しが発生した場合でも、ブラウザおよびエージェントレイヤーで先制的な防御壁を構築することが可能です。
ゼロトラストのサーバーサイド検証とFastifyスキーマ設計
クライアントサイドで宣言するWebMCP JSONスキーマは、完全なセキュリティ境界としての役割は果たせません。実際のブラウザエージェント環境では、バリデーションを経ない任意の追加プロパティや、宣言された仕様とは異なる型のデータがバックエンドに送信されることが頻繁に発生します。したがって、最終的な受信地であるFastifyバックエンドサーバーレベルで、厳格なスキーマベースのバリデーションを経る「ゼロトラスト」観点での再検証が不可欠です。
これを解決する最も確実な方法は、Fastify公式の型プロバイダーであるTypeBoxを活用して、ランタイム検証と型コンパイルを同期させることです。特にFastify環境でAjvオプションの removeAdditional: 'all' 設定を有効にすると、スキーマに定義されていない汚染されたプロパティを完全に遮断し、予期しないデータがビジネスロジックに流入する現象を防ぐことができます。
この構造を適用すれば、クライアントエージェントが予期せぬ引数を迂回注入しようとしても、サーバーへの進入段階で失敗処理されます。ブラウザ内部でのツール呼び出しが改ざんされても、サーバーが自らを保護できる最後の防衛線が構築されることになります。
段階的な機能向上で安全に始める
WebMCPは、Chrome 156までオリジントライアルが進行する初期段階の実験的仕様です。そのため実務に導入する際は、この機能がなくてもサービスの核となる機能が完全に動作するように、「段階的な機能向上(Progressive Enhancement)」の観点でアプローチする必要があります。ツールの公開範囲を最小限に抑え、すべての書き込み操作をバックエンド検証の背後に分離し、機密性の高い作業には人間が直接介入する手順を設けることが、エージェント環境を安全に構築するための近道です。
参考リンク
- Chrome for Developers — WebMCP Tool Security and Annotation Hints (Chrome for Developers)
- Chrome for Developers / W3C Web Machine Learning Community Group — Navigator.modelContext Deprecated in Chrome 150 in favor of Document.modelContext
- W3C Web Machine Learning Community Group / Flavio Copes — Cross-Origin Permissions Policy and Iframe Security in WebMCP