デスクトップアプリからブラウザを自動操作したい。 この要望は、RPAツールやAIエージェントの普及とともに増えている。 筆者自身も、ブラウザを自動制御する拡張機能を作りたいと考え、その技術的な仕組みを調査した。
しかし、ブラウザはセキュリティ上の理由からサンドボックス化されており、外部プロセスから直接操作することはできない。 では、Power Automate DesktopやClaude for Chromeといったツールは、どのようにしてこの制約を乗り越えているのか。
本記事では、ローカルアプリからChromeを自動制御する技術について、実際の製品のソースコード解析を交えながら解説する。 特に、2025年6月23日に公開されたClaude CodeのWebSocket Origin検証不足の脆弱性(CVE-2025-52882)を取り上げ、設計判断がセキュリティにどう影響するかを考察する。
この記事で扱うこと
- Chrome Native Messaging API、WebSocket、Chrome DevTools Protocolの比較
- アーキテクチャパターンの整理(Native Messagingのみ / Native Host + OS固有IPC / Native Host + WebSocket)
- Power Automate Desktop、Claude for Chromeのソースコード解析
- CVE-2025-52882の技術的な解説と対策
- セキュリティとクロスプラットフォームのトレードオフ
対象読者
- Chrome拡張機能を開発している、または開発予定の開発者
- デスクトップアプリとブラウザの連携を検討している開発者
- ローカル通信のセキュリティに関心のあるセキュリティエンジニア
- ローカルアプリとChrome拡張の連携には Native Messaging API が基本
- WebSocketはクロスプラットフォーム対応に便利だが、認証なしは危険
- CVE-2025-52882:Claude Code(※IDE拡張機能。本記事で実例として取り上げるClaude for Chromeとは別製品)でWebSocketのOrigin検証不足により、悪意あるWebサイトからローカルファイル読み取りが可能だった(CVSS 8.8)
- 教訓:「localhostは安全」は誤り。WebSocketには認証(ロックファイル + トークン等)が必須
ローカルアプリからChromeを操作するには、いくつかの技術的なアプローチがある。 それぞれの特徴と用途を整理する。
Chrome拡張機能とローカルアプリを接続するための公式API。
flowchart LR
A[ローカルアプリ] <-->|何らかの通信| B[Native Host stdin/stdout]
B <-->|Native Messaging| C[Chrome拡張]
仕組み
- Chrome拡張機能から
chrome.runtime.connectNative()またはchrome.runtime.sendNativeMessage()を呼び出す - Chromeが指定されたNative Host(実行ファイル)を起動
- 標準入出力(stdin/stdout)でJSONメッセージを交換
特徴
- Chromeが仲介するため、許可された拡張機能のみが接続可能
- マニフェストファイルでNative Hostの実行パスと許可する拡張機能IDを指定
- クロスプラットフォーム対応(Windows / macOS / Linux)
参考リンク
Chrome拡張機能からlocalhostのWebSocketサーバーに直接接続する方式。
flowchart LR
A[ローカルアプリ<br/>WSサーバー] <-->|ws://localhost| B[Chrome拡張]
仕組み
- ローカルアプリがWebSocketサーバーを起動(例:
ws://localhost:8080) - Chrome拡張機能のBackground ScriptからWebSocketで接続
- 双方向のリアルタイム通信が可能
特徴
- Native Hostを介さずシンプルに実装可能
- 複数クライアントからの同時接続に対応
- 認証を実装しないとセキュリティリスク(後述するCVE-2025-52882)
注意点
WebSocketはSame-Origin Policyの対象外であり、悪意のあるWebサイトからもws://localhostに接続可能。
この方式を採用する場合は、必ず認証機構を実装する必要がある。
Chromeのデバッグ機能を利用してブラウザを外部から制御するプロトコル。
flowchart LR
A[ローカルアプリ] <-->|CDP| B["Chrome<br/>(--remote-debugging-port)"]
仕組み
- Chromeを
--remote-debugging-port=9222オプション付きで起動 - 指定ポートにWebSocketで接続し、CDPコマンドを送信
- ページ操作、DOM操作、ネットワーク監視など幅広い機能を利用可能
特徴
- Chrome拡張機能が不要(ブラウザを直接制御)
- Puppeteer、Playwright、Seleniumなどの自動化ツールが内部で使用
- デバッグ用途が主であり、エンドユーザー向けアプリには不向き
用途
- E2Eテスト自動化
- Webスクレイピング
- ブラウザ自動操作ツール
参考リンク
ローカルアプリとChrome拡張を連携させる際のアーキテクチャは、大きく3つのパターンに分類できる。
最もシンプルな構成。 Native Hostがアプリ本体を兼ねるか、アプリ本体と同一プロセスで動作する。
flowchart TD
A["アプリ本体<br/>(= Native Host)"]
A -->|Native Messaging<br/>stdin/stdout| B[Chrome拡張機能]
特徴
- 構成がシンプルで実装が容易
- Native Hostの起動/終了がChromeに依存
- 常駐型アプリには不向き(Chromeを閉じるとNative Hostも終了)
適したユースケース
- 拡張機能からの要求に応答するだけのシンプルなツール
- CLIツールとの連携
Native Hostとアプリ本体を分離し、OS固有のIPCで通信する構成。 Power Automate Desktopが採用しているパターン。
flowchart TD
A[アプリ本体]
A -->|Named Pipe<br/>Unix Socket| B[Native Host]
B -->|Native Messaging<br/>stdin/stdout| C[Chrome拡張機能]
特徴
- アプリ本体は常駐可能(Chromeの起動状態に依存しない)
- OS固有のIPCはブラウザからアクセス不可能(セキュア)
- クロスプラットフォーム対応が困難
適したユースケース
- 常駐型のデスクトップアプリ
- エンタープライズ向けでセキュリティ要件が厳しい場合
- 単一OS向けのアプリ
Native Hostとアプリ本体をWebSocketで接続する構成。
flowchart TD
A[アプリ本体]
A -->|WebSocket<br/>ws://localhost| B[Native Host]
B -->|Native Messaging<br/>stdin/stdout| C[Chrome拡張機能]
特徴
- クロスプラットフォーム対応が容易
- WebSocketの柔軟性(双方向通信、複数クライアント対応)
- 認証を実装しないとセキュリティリスク(CVE-2025-52882)
適したユースケース
- macOS / Linux / Windows すべてに対応する必要がある場合
- 複数のクライアントから接続される可能性がある場合
- ただし、認証機構の実装が必須
| 項目 | パターンA | パターンB | パターンC |
|---|---|---|---|
| 構成の複雑さ | ◎ シンプル | △ やや複雑 | △ やや複雑 |
| アプリ常駐 | ✗ 不可 | ◎ 可能 | ◎ 可能 |
| セキュリティ | ◎ Chromeが仲介 | ◎ OSが保護 | △ 認証必須 |
| クロスプラットフォーム | ◎ | ✗ OS依存 | ◎ |
| 実装の容易さ | ◎ | ○ | ○(認証含む) |
パターン選択のフローチャート
flowchart TD
Q1{アプリは常駐する<br/>必要がある?}
Q1 -->|No| A[パターンA]
Q1 -->|Yes| Q2{クロスプラットフォーム<br/>対応が必要?}
Q2 -->|No| B["パターンB<br/>(Named Pipe / Unix Socket)"]
Q2 -->|Yes| C["パターンC<br/>(WebSocket + 認証必須)"]
Power Automate Desktop(PAD)は、MicrosoftのRPA(Robotic Process Automation)ツールであり、ブラウザ自動化機能を備えている。 Chrome拡張機能のソースコード解析から、そのアーキテクチャを推測する。
flowchart TD
A["Power Automate Desktop<br/>(Windows アプリ)"]
A -->|Named Pipe<br/>(推測)| B[Native Host]
B -->|Native Messaging<br/>stdin/stdout| C["Chrome拡張機能<br/>(Background Script)"]
C -->|chrome.scripting API| D["Webページ<br/>(Content Script)"]
Chrome拡張機能はchrome.runtime.connectNative()でNative Hostに接続し、半永続的な双方向通信を確立する。
注記: Native HostとPAD本体の間の通信方式について、公式ドキュメントには明記されていない。
MicrosoftはWindows環境でのプロセス間通信にWCF Named Pipeを多用しているため、同様の方式を採用していると推測される。
公式トラブルシューティングではcom.microsoft.pad.messagehostというNative Host名が言及されている。
主な機能として、タブ操作(取得・作成・削除・アクティブ化)、ページ操作(リロード・URL遷移)、DOM操作(クリック・テキスト入力・要素取得)、JavaScript実行(Debugger API経由)がある。
PADがNamed Pipeを採用していると推測される理由は、以下の通り。
Windows専用アプリである
PADはWindows専用のデスクトップアプリケーションであり、クロスプラットフォーム対応の必要がない。 そのため、Windows固有のIPCであるNamed Pipeを採用できた。
エンタープライズ向けのセキュリティ要件
PADは企業向けRPAツールであり、セキュリティ要件が厳しい。 Named PipeはOSレベルのアクセス制御(ACL)が適用されるため、不正アクセスを防ぎやすい。
高速な双方向通信
Named Pipeはカーネルレベルで実装されており、WebSocketよりも低オーバーヘッドで高速な通信が可能。
PADのアーキテクチャは、セキュリティ面で以下の特性を持つ。
ブラウザからのアクセス不可
Named Pipeはネットワークプロトコルではないため、ブラウザのJavaScriptからアクセスできない。 悪意のあるWebサイトがPADに接続することは構造的に不可能。
OSレベルの認証
Named Pipeへの接続はWindowsのセキュリティ機構で保護される。 適切なACL(Access Control List)を設定することで、許可されたプロセスのみが接続できる。
WebSocket型の脆弱性が構造的に排除される
WebSocketを使用していないため、ブラウザ経由のlocalhost接続脆弱性(CVE-2025-52882のようなパターン)は構造的に発生しない。
Claude for Chromeは、AnthropicのAIアシスタント「Claude」をブラウザから利用するための拡張機能。 Claude DesktopやClaude Codeと連携し、ブラウザ操作をAIエージェントが実行できる。
flowchart TD
A[Claude Desktop / Code]
A -->|OS固有IPC + MCP<br/>Unix Socket / Named Pipe| B["Native Host<br/>(chrome-native-host)"]
B -->|Native Messaging<br/>stdin/stdout| C["Chrome拡張機能<br/>(Background Script)"]
C -->|chrome.scripting API| D[Webページ]
PADと同様に、Native HostとClaude Desktop / Claude Codeの間の通信にOS固有のIPCを使用している。 少なくとも検証したOS(macOS/Windows)ではTCPポートを開かず、OS固有IPCでローカル通信している。
| OS | 通信方式 | 検証状況 |
|---|---|---|
| macOS | UNIXドメインソケット | macOSで確認(パスは環境依存) |
| Linux | UNIXドメインソケット(推測) | 未検証 |
| Windows | Named Pipe | Windowsで確認 |
パイプ名はclaude-mcp-browser-bridge-<username>形式でユーザー名を含む。
Claude for Chromeは、2つのNative Hostに対応している。
| Native Host名 | 対応アプリ |
|---|---|
com.anthropic.claude_browser_extension |
Claude Desktop |
com.anthropic.claude_code_browser_extension |
Claude Code |
拡張機能は起動時に両方への接続を試み、応答があった方と通信を確立する。
接続確認にはping/pongメッセージを使用し、10秒以内に応答がなければ次の候補を試す。
Claude for Chromeの通信は2層構造になっている。
第1層:Chrome拡張 ↔ Native Host
Chrome Native Messaging APIを使用。 これはPADと同じく、stdin/stdoutによるJSON通信。
第2層:Native Host ↔ Claude Desktop / Claude Code
OS固有IPC + MCP(Model Context Protocol)を使用。 MCPはAnthropicが策定したAIエージェント向けのプロトコルで、ツール実行やリソースアクセスを標準化している。
PADと同様に、Claude for Chromeもセキュリティ面で優れた特性を持つ(検証したmacOS/Windowsにおいて)。
ネットワークポート不使用(確認済み環境において)
少なくともmacOS/WindowsではTCPポートを開かず、ネットワーク経由の攻撃面が削減されている。
OS固有IPCによるローカル限定通信
UNIXドメインソケットやNamed Pipeはローカルプロセス間通信専用であり、ブラウザのJavaScriptからはアクセスできない。
OSレベルのアクセス制御
セキュリティ上重要なのはパイプ名よりも、ソケットファイル/Named PipeのOS権限(所有者・パーミッション/ACL)である。 ユーザー固有のパイプ名は、主に衝突回避や誤接続防止の意味合いを持つ。
注記:アプリケーション層のセキュリティ
なお、本記事で扱った通信層のセキュリティとは別に、Claude for Chromeはアプリケーション層でのセキュリティリスク(プロンプト注入攻撃)にも対処している。 詳細は公式ブログを参照されたい。
WebSocketをローカル通信に使う際には、見落としがちなセキュリティ上の落とし穴がある。 ここでは、Claude Code(IDE拡張機能)で発生したCVE-2025-52882を例に解説する。
2025年6月23日、Claude Code(VS Code / JetBrains拡張機能)に深刻な脆弱性が公開された。
基本情報
| 項目 | 内容 |
|---|---|
| CVE ID | CVE-2025-52882 |
| GHSA ID | GHSA-9f65-56v6-gxw7 |
| CVSSスコア | 8.8(高) |
| 脆弱性タイプ | CWE-1385: Missing Origin Validation in WebSockets |
| 発見者 | Datadog Security Labs |
影響を受けるバージョン
| プラットフォーム | 影響範囲 | 修正版 |
|---|---|---|
| VS Code / Cursor / Windsurf 等 | 0.2.116 〜 1.0.23 | 1.0.24 |
| JetBrains(IntelliJ / PyCharm 等) | 0.1.1 〜 0.1.8 | 0.1.9 |
脆弱性の本質
Claude CodeのMCPサーバーは、localhostにWebSocketサーバーを起動していた。 問題は、このWebSocketサーバーが接続元のOriginを検証していなかったこと。 任意のWebサイトからの接続を受け入れてしまう状態だった。
攻撃シナリオ
- 被害者が悪意あるWebサイトを訪問
- サイト上のJavaScriptがポートスキャンを実行
- MCPサーバーのWebSocketポートを発見
- 認証なしで接続し、JSON-RPCコマンドを送信
- ローカルファイルの読み取りやコード実行が可能に
ユーザーの操作はWebサイトを開くだけ。それ以外の操作は一切不要だった。
この脆弱性の根本原因は、「localhostにバインドすれば外部からアクセスできない」という誤解にある。
誤解:localhostは安全
flowchart LR
subgraph 開発者の想定
A1[ローカルプロセス] -->|ws://localhost| B1[MCPサーバー]
A1 -.->|✓ OK| B1
end
subgraph 外部からは不可能...のはず
A2[インターネット] -.-x|✗| B2[MCPサーバー]
end
現実:ブラウザからlocalhostに接続可能
flowchart TD
A[悪意あるWebサイト]
A -->|ブラウザ内のJavaScript| B["new WebSocket('ws://localhost:PORT')"]
B -->|認証なしで接続成功!| C[MCPサーバー]
なぜこれが可能なのか
WebSocketはSame-Origin Policyの対象外である。 通常のHTTPリクエスト(fetch, XMLHttpRequest)は、異なるオリジンへのリクエストがCORSで制限される。 しかし、WebSocketはこの制限を受けない。
ブラウザはws://localhostへの接続を許可しており、悪意のあるJavaScriptがローカルサービスに接続できてしまう。
ポートスキャンも可能
ブラウザJavaScriptでのポートスキャンには制限があるものの、デフォルトポートや既知のポート範囲を試すことで発見される可能性がある。
CVE-2025-52882の修正では、ロックファイル + トークン認証が採用された。 参照: https://securitylabs.datadoghq.com/articles/claude-mcp-cve-2025-52882/
修正後の認証フロー
sequenceDiagram
participant S as MCPサーバー
participant F as ロックファイル
participant C as Claude Code CLI
participant M as 悪意あるサイト
Note over S,F: 1. サーバー起動時
S->>S: ランダムトークン生成
S->>F: トークンを保存<br/>(パーミッション制限)
Note over C,S: 2. 正当なクライアント
C->>F: トークン読み取り
C->>S: WebSocket接続 + トークン
S->>S: トークン検証
S-->>C: ✓ 接続許可
Note over M,S: 3. 悪意あるサイト
M-xF: ファイル読み取り不可
M->>S: WebSocket接続(トークンなし)
S--xM: ✗ 接続拒否
なぜこれで解決するのか
ブラウザのJavaScriptには、ローカルファイルシステムへのアクセス権がない。 ロックファイルに保存されたトークンは、正当なローカルプロセスのみが読み取れる。 これにより、OSレベルのアクセス制御を認証に活用している。
他の解決策との比較
| 解決策 | セキュリティ | 実装コスト | 備考 |
|---|---|---|---|
| ロックファイル + トークン | ◎ | 低 | 採用された方式 |
| Origin検証 | ○ | 低 | ブラウザ経由には有効(※) |
| Named Pipe / Unix Socket | ◎ | 中 | WebSocket廃止が必要 |
| ワンタイムトークン | ◎ | 中 | より堅牢だが実装が複雑 |
※ Origin検証について
ブラウザはOriginヘッダを強制的に付与し、JavaScriptから改変できない。 そのため、今回の攻撃シナリオ(ブラウザ内JavaScript)に限定すれば、Origin検証だけでも防げる。 ただし、以下のケースには無力なため、トークン認証との併用が推奨される。
- DNS Rebinding攻撃:正規のOriginに見せかける高度な攻撃
- 非ブラウザクライアント:curl等ではOriginヘッダを任意に設定可能
Power Automate DesktopとClaude for Chromeの比較から見えてきた、設計判断のポイントを整理する。
ローカルアプリとChrome拡張の連携において、最も重要なトレードオフは「セキュリティ」と「クロスプラットフォーム対応」である。
セキュリティを優先する場合(PADの選択)
- Named Pipe(Windows)やUnix Socket(macOS/Linux)を採用
- OSレベルのアクセス制御で保護
- ブラウザからのアクセスを構造的に排除
- その代わりOS固有の実装が必要
クロスプラットフォームを優先する場合
- WebSocketを採用(全OSで動作)
- 実装がシンプルで開発効率が高い
- その代わり認証機構の実装が必須(怠るとCVE発生)
なお、Claude for Chromeは当初WebSocket方式と推測されていたが、実際にはOS固有IPC(macOS/Windowsで確認)を使用しておりパターンBに該当する。 クロスプラットフォーム対応はOS判定による分岐で実現していると考えられる。
どちらを選ぶべきか
| 条件 | 推奨 |
|---|---|
| 単一OS向け | Named Pipe / Unix Socket |
| エンタープライズ向け | Named Pipe / Unix Socket |
| 個人向けクロスプラットフォーム | WebSocket + 認証 |
| 開発リソースが限られている | WebSocket + 認証 |
Chrome拡張からWebSocketで直接接続する方式(Native Hostなし)も技術的には可能。 では、なぜPADもClaude for ChromeもNative Hostを採用しているのか。
Native Hostを使う理由
-
Chromeの起動に依存しない常駐
- アプリ本体はChromeが閉じても動作し続ける
- Native Hostは必要なときだけ起動し、アプリ本体と通信
-
OS固有IPCの使用が可能
- Native Hostなしの場合、WebSocketで直接接続するしかない
- Native Hostを介することで、Named Pipe/UNIXドメインソケットが選択肢になる
- これによりブラウザからのアクセスを構造的に排除できる
-
権限の分離
- Chrome拡張はサンドボックス内で動作し、ファイルシステムに直接アクセスできない
- Native Hostを介することで、必要な権限(ファイル操作等)を安全に委譲できる
Native Hostが不要なケース
- 拡張機能だけで完結する機能
- アプリ側から拡張機能への一方通行の通信
- 開発・デバッグ用途
最後に、ローカルIPCの選択基準をまとめる。
| 方式 | セキュリティ | クロスプラットフォーム | 実装コスト | 推奨シーン |
|---|---|---|---|---|
| Named Pipe | ◎ | ✗ Windows | 中 | エンタープライズ向け |
| Unix Socket | ◎ | △ macOS/Linux | 中 | サーバー向け |
| WebSocket + 認証 | ○ | ◎ | 中 | 個人向けクロスプラットフォーム |
| WebSocket(認証なし) | ✗ | ◎ | 低 | 使用禁止 |
選択フロー
flowchart TD
Q1{Q1. クロスプラットフォーム<br/>対応が必要?}
Q1 -->|No| Q2{Q2. 対象OSは?}
Q1 -->|Yes| WS["WebSocket +<br/>ロックファイル認証"]
Q2 -->|Windows| NP[Named Pipe]
Q2 -->|macOS/Linux| US[Unix Socket]
Q2 -->|複数| BOTH["各OSごとに実装<br/>or WebSocket + 認証"]
WS --> Q3{Q3. 認証は?}
BOTH --> Q3
Q3 -->|実装済み| OK[✓ OK]
Q3 -->|未実装| NG["⚠ CVE発生リスク<br/>必ず実装"]
style NG fill:#f66,stroke:#333
style OK fill:#6f6,stroke:#333
最も重要なこと
「ローカルだから安全」という思い込みを捨てる
WebSocketをローカル通信に使う場合、認証は必須。 これはCVE-2025-52882が示した教訓であり、すべての開発者が心に留めるべきポイントである。
ローカルアプリからChromeを自動制御する技術について、実例とともに解説した。
Power Automate DesktopはWindows専用という制約を活かし、Named Pipeによるセキュアな通信を実現していると推測される。 Claude for Chromeも同様に、OS固有IPC(macOSではUNIXドメインソケット、WindowsではNamed Pipe。Linuxは未検証だが同様と推測)を使用したパターンBを採用しており、WebSocket型の脆弱性を構造的に排除している。
一方、Claude Code(IDE拡張機能)のMCPサーバーはクロスプラットフォーム対応のためにWebSocketを採用していたが、Origin検証の欠如がCVE-2025-52882を引き起こした。
両者の比較から得られた教訓は明確である。
- Named Pipe / Unix Socket:OSレベルの保護があり、ブラウザからアクセス不可能
- WebSocket:クロスプラットフォーム対応が容易だが、認証なしでは脆弱性の温床
WebSocketをローカル通信に採用する場合、ロックファイル + トークン認証のような仕組みが必須である。 「localhostにバインドすれば安全」という思い込みは危険であり、Same-Origin PolicyがWebSocketに適用されない事実を常に念頭に置くべきである。
公式ドキュメント
- Chrome Native Messaging - Chrome拡張からローカルアプリに接続するための公式API
- Chrome DevTools Protocol - ブラウザを外部から制御するプロトコル
CVE-2025-52882関連
- GitHub Advisory - GHSA-9f65-56v6-gxw7 - 一次情報(GitHub Security Advisory)
- Anthropic Security Advisory - Anthropic公式セキュリティアドバイザリ
- Datadog Security Labs - CVE-2025-52882 - 発見者による技術解説
- CVE-2025-52882 - NVD - 脆弱性データベース
Claude for Chrome関連
- Piloting Claude for Chrome - 公式ブログ - Claude for Chromeの機能とセキュリティ対策
- Claude - Chrome Web Store - Claude for Chrome拡張
Power Automate Desktop関連
- Microsoft Power Automate - Chrome Web Store - Power Automate DesktopのChrome拡張