Windows版OpenCodeのMCP OAuthサインインRCE、1.18.33で修正
WindowsとWSL上のOpenCode 1.0.137~1.18.32では、悪意あるMCPサーバーのOAuthサインインURLがPowerShellに届き、開発者としてコードを実行します。1.18.33で修正済みで、CVEはありません。
要点
- MCP OAuthのサインインでは、認証対象のサーバーが開発者のブラウザーを誘導するWebアドレスを選びます。WindowsとWSL上のOpenCode 1.0.137~1.18.32は、そのサーバー制御のURLを
openパッケージへ渡していました。同パッケージはエスケープせずPowerShellコマンドに組み込むため、PowerShellの部分式を含むアドレスが開発者として実行されました。 - 発見して2026年8月29日に非公開で報告したPillar Securityは、クリティカル、CVSS v3.1 9.8(
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)、CWE-78を提案しています。これはPillarの提案評価です。記載された攻撃には開発者によるopencode mcp authの実行が必要で、その後のハンドシェイクには追加の確認や同意は不要です。CVEもベンダーアドバイザリもありません。開発元Anomalyは悪意あるリモートMCPサーバーを脅威モデルの対象外と考えており、公開アドバイザリとバージョンを照合するスキャナーには、この欠陥のレコードがありません。 - macOSとLinuxは、URLをシェル経由にせずブラウザーを開くため影響を受けません。悪用は報告されておらず、Pillarは侵害指標を公開していません。
- 2026年9月28日公開のOpenCode 1.18.33以降へアップグレードしてください。まだ難しい場合は、WindowsとWSLのOpenCode設定から、十分に検証していないリモートMCPサーバーをすべて削除してください。
影響を受けるか
WindowsまたはWSLでopencode-ai 1.0.137~1.18.32、または@opencode/cli 2.0.0~2.0.17を使い、応答を自分で制御できないリモートMCPサーバーのサインインを開始すると影響を受けます。次のすべてが必要です。
- WindowsまたはWindows Subsystem for Linux(WSL)でOpenCodeを実行。macOSとLinuxのブラウザー起動はURLをシェルに渡さないため影響なし
opencode-aiが1.0.137~1.18.32、または@opencode/cliが2.0.0~2.0.17(端点を含む)- 応答を完全には制御できないリモートMCPサーバーを少なくとも一つ設定。設定時に悪意があった必要はありません。ペイロードはサインイン時のHTTPレスポンスで届くため、後日侵害されたサーバー、乗っ取られたレジストリエントリ、タイポスクワッティング、期限切れ後に所有者が変わったドメインでも同じアドレスを運べます。
- 開発者が
opencode mcp authでそのサーバーのサインインを開始。設定済みであることやセッションを開くだけでは、ブラウザー起動段階に到達しません。
| パッケージ | 影響を受けるバージョン | 修正バージョン |
|---|---|---|
| npmのopencode-ai、WindowsとWSL | 1.0.137~1.18.32 | 1.18.33(2026年9月28日) |
| npmのopencode-ai、macOSとLinux | 影響なし | 該当なし |
| npmの@opencode/cli、WindowsとWSL | 2.0.0~2.0.17 | 2.0.18(2026年9月25日) |
opencode-aiは2026年10月16~22日にnpmで2,180,172回ダウンロードされています。ダウンロード数は普及範囲の指標であり、影響するインストール数ではありません。
使用バージョンと設定済みサーバーを確認します。
opencode mcp list # which MCP servers are configured
npm ls -g opencode-ai @opencode/cli 2>/dev/null # npm installs and their versions
brew list --versions opencode 2>/dev/null # Homebrew installs
修正は2026年9月25日から共有ソースツリーにあるため、どちらのパッケージも現行リリースに更新すれば解消します。Pillar Securityの開示一覧はopencode-ai系列を対象としています。
修正方法
opencode-aiを1.18.33以降、または@opencode/cliを2.0.18以降にアップグレードします。
npm i -g opencode-ai@latest
@opencode/cli系列の場合は次を実行します。
npm i -g @opencode/cli@latest
WindowsまたはWSLの端末をまだ更新できない場合は、次を実施します。
- 検証していないリモートMCPサーバーを、その端末のOpenCode設定からすべて削除する(
opencode mcp listで残るものを確認) - 削除できないサーバーは、危険を受け入れているものとして扱う。サインインページがペイロードの到着点になる
- 自分でインストールしたコマンドを実行するローカルMCPサーバーは、この経路の対象外。必要なのはリモートサーバーのOAuthハンドシェイク
根本原因
OAuthのディスカバリーハンドシェイクがリモートMCPサーバーにサインインURLを選ばせ、Windows版OpenCodeがその信頼できないURLをブラウザー起動ヘルパーへ渡し、ヘルパーがエスケープせずPowerShellコマンドへ展開しました。
OpenCode 1.18.32では、サーバーのディスカバリー文書が指定する自由な文字列authorization_endpointが、MCP SDKからoauth-provider.ts、mcp/index.ts、browser.tsを通り、最後にopen()へ届きます。OpenCodeは2025年12月7日のコミット509e43d6で、サーバー提供URLをopen()へ渡す呼び出しを追加し、openを10.1.2に固定していました。
macOSとLinuxでは、openは引数ベクトルを使ったspawnでopenまたはxdg-openを実行するため、シェルは関与しません。Windowsではopen 10.1.2がPowerShellコマンドを構築し、ソースが示すとおりエスケープ処理が非対称です。
// open@10.1.2, the Windows path (lines 242 to 256)
242: encodedArguments.push(`"\`${app}\`""`); // app gets escaped
247: encodedArguments.push(`"${options.target}"`); // target does not
256: options.target = Buffer.from(
encodedArguments.join(' '), 'utf16le').toString('base64');
242行目はアプリケーション名をエスケープします。リモートURLが入る247行目のtargetは、まったくエスケープしません。結合された引数はbase64エンコードされ、powershell -EncodedCommandへ渡されます。
PowerShellは二重引用符内の$(...)部分式を展開します。これが欠陥です。MCPサーバーの応答を制御する者が選んだリモート文字列が、サインイン時に開発者の端末で実行されるPowerShellコマンドの一部になります。
悪用の仕組み
攻撃は報告されておらず、PoCはPillar Securityの開示で公開されています。ペイロードは通常のHTTPSアドレスです。
https://evil.test/$([IO.File]::WriteAllText('C:\Users\Public\pwned.txt','RCE'))
攻撃を順に説明します。
- 攻撃者が、開発者の設定したリモートMCPサーバーを制御するか、サインイン時に影響できる状態にします。サーバー乗っ取り、レジストリの乗っ取り、タイポスクワッティング、期限切れ後のドメイン取得などです。
- 開発者が
opencode mcp authでサインインを開始します。ハンドシェイクは設計上自動なので、追加の操作や同意は不要です。 - サーバーのディスカバリー文書が、細工したURLを
authorization_endpointとして返します。 - OpenCodeがURLを
open10.1.2へ渡し、それがエスケープせずPowerShellコマンドに展開して実行します。 - PowerShellはコマンドを解決する前に
$(...)部分式を評価します。その後ブラウザー起動に失敗しても、ペイロードは実行済みです。OpenCodeはその失敗を捨てます。
ペイロードは、開発者の認証情報、トークン、ソースツリー、CIアクセスを持つ端末上で、開発者自身の権限で動きます。
攻撃フロー
サーバーが制御する一つのURLが、サインイン時にPowerShellコマンドになります。
サインインを開始"] --> B["サーバーのディスカバリー文書が
細工したURLを返す"] B --> C["WindowsまたはWSLでOpenCodeが
open@10.1.2へURLを渡す"] C --> D["openがPowerShellコマンドを構築
対象URLはエスケープされない"] D --> E["起動前にPowerShellが
$(...)部分式を評価"] E --> F["開発者としてペイロードが動作
起動失敗は捨てられる"] style D fill:#f8d7da
欠陥はDです。サーバー提供URLがコマンドラインへ入る前に、エスケープする処理がありませんでした。
攻撃者に可能なこと
WindowsまたはWSL端末で開発者として任意コードを実行できます。実務上は、ソースツリー、ディスク上の認証情報やトークン、gitやクラウドのCLI、CIアクセス、エージェントが通信できるMCPサーバーなど、開発者の到達範囲すべてに及びます。Pillarはクリティカル、提案CVSS v3.1 9.8(AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)、CWE-78、補助的にCWE-88としています。
攻撃に必要な条件です。
- WindowsまたはWSLで
opencode-ai1.0.137~1.18.32、または@opencode/cli2.0.0~2.0.17を使用。macOSとLinuxはURLをシェルに渡さない - サインイン時に攻撃者がOAuthディスカバリーレスポンスを制御するリモートMCPサーバー。設定時に悪意があった必要はない
- 開発者がそのサーバーのサインインを開始。それ以外の確認や追加同意は不要
- スキーム検証では防げない。ペイロードは通常の
https://URLで、MCP TypeScript SDKのjavascript:/data:/vbscript:拒否リストと、OpenCodeの新しい2つのチェックを通過する。SDKが検討したが未導入の、より厳しいhttp/https許可リストも通過する
修正が機能する理由
プルリクエスト#51414でコミット29f07e0cとしてマージされたOpenCode 1.18.33は、3層で修正します。その順序が重要です。
--- a/packages/core/src/open.ts (new file)
+import open from "open"
+
+export function openUrl(input: string) {
+ const url = URL.canParse(input) ? new URL(input) : undefined
+ if (!url || (url.protocol !== "http:" && url.protocol !== "https:"))
+ return Promise.reject(new Error(`Only http and https links can be opened in the browser: ${input}`))
+ return open(url.href)
+}
--- a/packages/opencode/src/mcp/oauth-provider.ts
async redirectToAuthorization(authorizationUrl: URL): Promise<void> {
+ if (authorizationUrl.protocol !== "http:" && authorizationUrl.protocol !== "https:")
+ throw new Error(
+ `MCP server "${this.serverUrl}" returned a ${authorizationUrl.protocol} authorization URL; only http and https are supported`,
+ )
await this.callbacks.onRedirect(authorizationUrl)
}
--- a/package.json
- "open": "10.1.2"
+ "open": "11.0.4"
公開ペイロードを実際に止めるのは依存関係の更新です。2025年11月15日にコミット274d704で公開されたopen 11.0.0は、対象を単一引用符で囲みます。PowerShellはその中を展開しません。OpenCodeが10.1.2へ固定したままの間、修正は10か月前から存在していました。脆弱なawait open(authorizationUrl)呼び出しを追加したのは、修正版openの公開から3週間後です。
2つのスキームチェックは多層防御です。範囲を正確に理解する必要があります。上記ペイロードはhttps://なので、両方を通過します。openの更新がなければ、完全に見える修正でも穴は残ったはずです。
この経路に対する修正は完全です。すべてのブラウザー起動箇所がopenUrlを通り、OAuthの境界自体でもhttp(s)以外のエンドポイントを拒否します。アドバイザリもCVEもありません。問い合わせに対するAnomalyの立場は、悪意あるMCPサーバーは脅威モデルの対象外というものです。そのため変更は、opencodeとtuiパッケージでブラウザー起動処理を共有するリファクタリングとしてのみ公開されました。差分は公開されていますが、公開アドバイザリとバージョンを照合するスキャナーにはレコードがありません。
侵害されたかを確認する方法
Pillar Securityは攻撃利用の兆候を報告しておらず、指標も公開していません。影響バージョンでリモートMCPサーバーを設定していたWindowsとWSL端末では、次を確認します。
opencode mcp listを実行し、全リモートサーバーの出所をレビューする。公開者、登録先、設定後にドメインやレジストリエントリの所有者が変わり得たかを確認- 1.0.137~1.18.32の端末で、MCPサインインの前後に説明できないプロセスやファイルが生成されていれば、開発端末侵害の標準対応を行う理由として扱う。到達可能な全認証情報、トークン、キーをローテーションし、正常と確認できる状態から環境を再構築
- 別のインシデントにも注意する。同時期に開示されたOpenCodeのホスト型Consoleの侵害では、一部ユーザーが保存したOpenAI、Anthropic、GoogleのAPIキーが露出した可能性がある。これはクライアント内の本欠陥とは別の事象
経緯
- 2020-10-22:
openissue #202が、WSL 2で$入りURLの文字が失われると報告。リンク不具合として扱われ、PowerShell文字列展開と理解される5年前。 - 2021-09-17:
openのREADMEが、セキュリティを保証せず、信頼できない入力のサニタイズは呼び出し元の責任とする免責を追加。 - 2023-07-24:
openissue #318と#319がPowerShellの引数エスケープを扱う。 - 2023-10-18:
openissue #323が、URLを開く際のWindows上のOSコマンドインジェクションを1行のPoCで報告。機能強化と分類され、後に対応予定なしで終了。 - 2025-07-09:mcp-remoteプロキシの同じ欠陥CVE-2025-6514(9.6)が公開され、JFrogの分析が
open()をシンクと特定。 - 2025-08-28および2025-09-17:openmcp-clientのCVE-2025-58062、sequa-mcpのCVE-2025-10619が同じシンクに対応。
- 2025-11-15:
open11.0.0がコミット274d704でPowerShell引数のエスケープを修正し、リリースノートのFixesに掲載。 - 2025-12-07:修正版
open公開の3週間後、OpenCodeのコミット509e43d6がMCP OAuth経路へawait open(authorizationUrl)を追加し、open10.1.2に固定。 - 2026-08-29:Pillar Securityが完全な再現資料を添え、GitHub Security Advisoryで非公開報告。
- 2026-09-25:プルリクエスト#51414がリファクタリングとしてコミット29f07e0cにマージ。Anomalyはチームへの報告到着を確認し、悪意あるMCPサーバーは脅威モデル外と回答。
- 2026-09-28:OpenCode 1.18.33が修正を含めnpmへ公開。
- 2026-10-19:Anomalyへ再考とCVE申請を求めた後、Pillar Securityが開示を公開。
- 2026-10-26:本記事を公開。
よくある質問
スキャナーがこの脆弱性を警告しない理由は?
Anomalyが修正後に申請していないため、CVEもベンダーアドバイザリもなく、脆弱性データベースに照合対象がありません。影響範囲は、リファクタリングとして公開された修正とPillarの開示からしかわかりません。アドバイザリ依存のスキャナーだけに頼らず、npm ls -g opencode-ai @opencode/cliでバージョンを確認し、opencode mcp listで設定済みサーバーを確認する必要があります。
URLスキーム検証で防げるか?
いいえ。公開ペイロードは普通のhttps:// URLで、MCP TypeScript SDKのjavascript:、data:、vbscript:拒否リストと、OpenCode 1.18.33の2つのチェックを通過します。SDKが検討したものの未導入の厳しいhttp/https許可リストも通過します。実際に穴を閉じたのは、対象を単一引用符で囲みPowerShellの展開を防ぐopen 11.0.0以降への更新です。OpenCodeは11.0.4へ更新しました。
macOSとLinuxも影響を受けるか?
いいえ。その環境ではopenは引数ベクトルを使うspawnでブラウザーを起動し、シェルコマンドを構築せず文字列を展開しません。PowerShell経路を使うのはWindowsとWSLだけです。
報道されているOpenCode Console侵害と同じか?
いいえ。Consoleの侵害は同時期の別の事象で、保存済みのOpenAI、Anthropic、GoogleのAPIキーが露出した可能性があります。本欠陥はMCPサインインを通じて開発者の端末でコードを実行し、OpenCode自身のシステム侵害は必要ありません。
どのMCPクライアントが適切に対処しているか?
Pillarのレビューは、いくつかの方法を挙げています。
- gemini-cliは、スキームを制限する
execFile起動処理を使い、シェルを使わない - Claude Codeは起動処理を保護し、OAuth経路からサーバー制御値で到達できないようにする
- github-mcp-serverは、相手から検出せず、運用者から認可エンドポイントを取得
- Docker mcp-gatewayは、https許可リストとargv起動処理で全OAuthエンドポイントを検証
これらの方法は、リモートサーバーの文字列がシェル構文になることを防ぎます。
今すぐアップグレードできない場合は?
WindowsとWSLのOpenCode設定から、十分に検証していないリモートMCPサーバーをすべて削除し、opencode mcp listで再確認してください。自分で入れたコードを実行するローカルMCPサーバーは対象外です。本件にはリモートサーバーのOAuthハンドシェイクが必要です。
未修正のOpenCode範囲をスキャン
Ostorlab Source Code Security Testingでリポジトリをレビューしてください。開発端末とCIイメージ内でnpm ls -g opencode-ai @opencode/cliを実行し、opencode-ai 1.0.137~1.18.32または@opencode/cli 2.0.0~2.0.17を確認します。これにより、アドバイザリに基づく警告を待たずに影響範囲を特定できます。
参考資料
- Pillar Security、「Open and Shut: Remote Code Execution in opencode via MCP OAuth」、2026年10月19日。根本原因、引用した
open10.1.2のソース、PoC、影響一覧、開示の経緯を含む:https://www.pillar.security/blog/open-and-shut-remote-code-execution-in-opencode-via-mcp-oauth (2026年10月26日確認) - OpenCodeリポジトリanomalyco/opencode:https://github.com/anomalyco/opencode (2026年10月26日確認)
- 2025年12月7日に
await open(authorizationUrl)を追加した脆弱なコミット509e43d6:https://github.com/anomalyco/opencode/commit/509e43d6 (Pillar Security経由の参照、2026年10月26日) - 2026年9月25日にコミット29f07e0cとしてマージされた修正プルリクエスト#51414:https://github.com/anomalyco/opencode/pull/51414 および https://github.com/anomalyco/opencode/commit/29f07e0c (2026年10月26日確認)
- 2026年9月28日公開のnpm上のOpenCode 1.18.33と、影響系列が1.0.137(2025年12月9日)から1.18.32(2026年9月21日)までであると確認できる時刻情報:https://www.npmjs.com/package/opencode-ai/v/1.18.33 および https://registry.npmjs.org/opencode-ai (2026年10月26日確認)
- v2の修正PR #51412と、v2.0.17の
open10.1.2からv2.0.18の11.0.4への変更を示すタグのマニフェスト:https://github.com/anomalyco/opencode/pull/51412, https://github.com/anomalyco/opencode/blob/v2.0.17/packages/cli/package.json および https://github.com/anomalyco/opencode/blob/v2.0.18/packages/util/package.json; npm公開時刻:https://registry.npmjs.org/@opencode/cli (2026年10月28日確認) - 固定バージョン
open10.1.2のWindows経路:https://github.com/sindresorhus/open/tree/v10.1.2 (2026年10月26日確認) - 2020年10月22日のWSL 2で
$を含むURLに関するopenissue #202、2023年10月18日のWindowsのOSコマンドインジェクションissue #323、2025年11月15日のopen 11.0.0修正コミット274d704:https://github.com/sindresorhus/open/issues/202, https://github.com/sindresorhus/open/issues/323 および https://github.com/sindresorhus/open/commit/274d704 (2026年10月26日確認) - mcp-remoteの同じシンクCVE-2025-6514、CVSS v3.1 9.6、JFrogの分析:https://nvd.nist.gov/vuln/detail/CVE-2025-6514 および https://jfrog.com/blog/2025-6514-critical-mcp-remote-rce-vulnerability/ (Pillar Security経由の参照、2026年10月26日)
- 同じシンクを持つopenmcp-clientのCVE-2025-58062とsequa-mcpのCVE-2025-10619:https://nvd.nist.gov/vuln/detail/CVE-2025-58062 および https://nvd.nist.gov/vuln/detail/CVE-2025-10619 (Pillar Security経由の参照、2026年10月26日)
- OpenCodeの欠陥に関する2026年10月22日のThe Hacker News報道:https://thehackernews.com/2026/10/opencode-flaw-lets-malicious-mcp.html (2026年10月26日確認)
- 別件のOpenCode Console侵害に関するThe Hacker News報道:https://thehackernews.com/2026/10/opencode-console-breach-may-have.html (OpenCode記事経由の参照、2026年10月26日)
- 2026年10月22日までの週のnpmダウンロード数。opencode-aiが2,180,172、@opencode/cliが321,091:https://api.npmjs.org/downloads/point/2026-10-16:2026-10-22/opencode-ai および https://api.npmjs.org/downloads/point/last-week/@opencode/cli (2026年10月26日確認)
- openパッケージのnpm週次ダウンロード数、2026年10月22日までの週に102,012,551:https://api.npmjs.org/downloads/point/last-week/open (2026年10月26日確認)
- anomalyco/opencodeのGitHubスター数、2026年10月26日時点で221,765:https://api.github.com/repos/anomalyco/opencode (2026年10月26日確認)