OpenCode 在 Windows 上的 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 登录期间,被验证的服务器决定开发者浏览器前往的地址。在 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,也没有厂商公告:OpenCode 开发者 Anomaly 认为恶意远程 MCP 服务器不在其威胁模型内,因此按已发布公告匹配版本的扫描器没有此漏洞记录。 - macOS 和 Linux 不受影响,因为 OpenCode 在这些平台打开浏览器时不会将 URL 经过 shell。未报告通过此漏洞实施的攻击,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 经过 shell。
- 版本为
opencode-ai1.0.137 至 1.18.32(含),或@opencode/cli2.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 日记录了 2,180,172 次 npm 下载。下载量是覆盖范围指标,不是受影响安装数量。
检查正在运行的版本和配置的服务器:
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 机器:
- 从该机器的 OpenCode 配置中移除所有未经审查的远程 MCP 服务器(
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,不涉及 shell。在 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 行转义应用名称。第 247 行的 target,恰好是远程 URL 落入的位置,完全未转义。拼接后的参数经过 base64 编码,交给 powershell -EncodedCommand。
PowerShell 会展开双引号字符串中的 $(...) 子表达式。这就是漏洞:由控制 MCP 服务器响应的一方选择的远程字符串,成为开发者机器在登录时执行的 PowerShell 命令的一部分。
如何利用?
尚未报告攻击,概念验证已在 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 命令。
MCP 服务器登录"] --> B["服务器发现文档
返回特制 URL"] B --> C["OpenCode 将 URL 交给 Windows
或 WSL 上的 open@10.1.2"] 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 经过 shell。 - 攻击者在登录时控制远程 MCP 服务器的 OAuth 发现响应。它在配置时不必已经恶意。
- 开发者启动该服务器登录。除此之外无需任何提示或额外同意。
- 协议方案验证无济于事:载荷是普通
https://URL。它能通过 MCP TypeScript SDK 的javascript:/data:/vbscript:拒绝列表,以及 OpenCode 新增的两项协议检查。它也能通过 SDK 曾考虑但未发布的更严格 http/https 允许列表。
为什么修复有效?
OpenCode 1.18.33 的修复通过拉取请求 #51414、提交 29f07e0c 合入,从三个层面关闭漏洞,顺序很重要:
--- 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"
真正阻止公开载荷的是依赖升级。open 11.0.0 于 2025 年 11 月 15 日发布,提交 274d704 将目标包在单引号中,而 PowerShell 不会展开单引号内的任何内容。该修复已存在十个月,OpenCode 却始终固定在 10.1.2。OpenCode 添加存在漏洞的 await open(authorizationUrl) 调用时,修复后的 open 已发布三周。
两项协议检查属于纵深防御,应准确说明其能力:上述载荷是 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:
open问题 #202 报告含$的 URL 在 WSL 2 上丢失字符,当时按损坏链接提交,五年后才被理解为 PowerShell 字符串展开。 - 2021-09-17:
openREADME 添加持续沿用的声明,表示该包不提供安全保证,净化不可信输入是调用方责任。 - 2023-07-24:
open问题 #318 和 #319 涉及 PowerShell 参数转义。 - 2023-10-18:
open问题 #323 报告 Windows 打开 URL 时发生操作系统命令注入,并附单行概念验证;它被标为功能增强,后来以“不计划处理”关闭。 - 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 参数转义,发布说明将其列在修复项下。 - 2025-12-07:OpenCode 提交 509e43d6 向 MCP OAuth 路径添加
await open(authorizationUrl),固定open10.1.2,此时修复后的open已发布三周。 - 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:Pillar Security 发布披露,此前曾要求 Anomaly 重新考虑并申请 CVE。
- 2026-10-26:本文发布。
常见问题
为什么扫描器不会标记此漏洞?
没有 CVE,也没有厂商公告,因为 Anomaly 修复后没有申请两者,漏洞数据库因此无从匹配。受影响范围仅能从作为重构发布的修复及 Pillar 披露中得知。发现受影响安装需要使用 npm ls -g opencode-ai @opencode/cli 检查 npm 包版本,并使用 opencode mcp list 审查配置的 MCP 服务器,而不能依赖公告驱动的扫描器。
URL 协议方案验证能阻止攻击吗?
不能。公开载荷是普通 https:// URL。它能通过 MCP TypeScript SDK 对 javascript:、data: 和 vbscript: 的拒绝列表,以及 OpenCode 在 1.18.33 添加的两项协议检查。它也能通过 SDK 曾考虑但未发布的更严格 http/https 允许列表。真正关闭漏洞的是将 open 升级到 11.0.0 或更高版本(OpenCode 升至 11.0.4),通过单引号包围目标,使 PowerShell 不再展开。
macOS 和 Linux 安装受影响吗?
不受影响。在这些平台,open 通过 spawn 和参数向量启动浏览器,不构建 shell 命令,也不执行字符串插值。只有 Windows 和 WSL 构建采用 PowerShell 路径。
这与新闻中的 OpenCode Console 入侵是同一事件吗?
不是。Console 入侵是同期披露的独立事件,可能泄露存储的 OpenAI、Anthropic 和 Google API 密钥。此次漏洞通过 MCP 登录在开发者机器上执行代码,不需要攻陷 OpenCode 自身系统。
哪些 MCP 客户端正确处理了这个问题?
Pillar 的审查发现了几种方法:
- gemini-cli 使用带协议限制、无需 shell 的
execFile打开器。 - Claude Code 保护打开器,使 OAuth 路径无法用服务器控制的值到达它。
- github-mcp-server 从操作人员获取授权端点,而不是从对端发现。
- Docker mcp-gateway 通过 https 允许列表验证每个 OAuth 端点,并使用 argv 打开器。
这些方法阻止远程服务器字符串变为 shell 语法。
如果现在无法升级怎么办?
从 Windows 和 WSL 机器的 OpenCode 配置中移除所有未经充分审查的远程 MCP 服务器,并通过 opencode mcp list 复查。运行您自行安装代码的本地 MCP 服务器不在此漏洞路径中,该路径需要远程服务器的 OAuth 握手。
扫描未修补的 OpenCode 版本范围
使用 Ostorlab 源代码安全测试审查仓库。在开发者机器和 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:通过 MCP OAuth 在 opencode 中远程执行代码》,2026 年 10 月 19 日,包含根本原因、引用的
open10.1.2 源码、概念验证、受影响矩阵及披露时间线: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 日核查)
- 引入漏洞的提交 509e43d6,于 2025 年 12 月 7 日添加
await open(authorizationUrl):https://github.com/anomalyco/opencode/commit/509e43d6 (通过 Pillar Security 引用,2026 年 10 月 26 日) - 修复拉取请求 #51414,2026 年 9 月 25 日作为提交 29f07e0c 合入:https://github.com/anomalyco/opencode/pull/51414 和 https://github.com/anomalyco/opencode/commit/29f07e0c (2026 年 10 月 26 日核查)
- npm 上的 OpenCode 1.18.33,2026 年 9 月 28 日发布;版本时间戳确认受影响分支为 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 日核查) open包 10.1.2,固定版本的 Windows 路径:https://github.com/sindresorhus/open/tree/v10.1.2 (2026 年 10 月 26 日核查)open问题 #202,2020 年 10 月 22 日,WSL 2 上含$的 URL;问题 #323,2023 年 10 月 18 日,Windows 操作系统命令注入;以及 open 11.0.0 的修复提交 274d704,2025 年 11 月 15 日:https://github.com/sindresorhus/open/issues/202, https://github.com/sindresorhus/open/issues/323 和 https://github.com/sindresorhus/open/commit/274d704 (2026 年 10 月 26 日核查)- CVE-2025-6514,mcp-remote 中的同一危险接收点,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 日)
- The Hacker News 对 OpenCode 漏洞的报道,2026 年 10 月 22 日:https://thehackernews.com/2026/10/opencode-flaw-lets-malicious-mcp.html (2026 年 10 月 26 日核查)
- The Hacker News 对独立 OpenCode Console 入侵的报道:https://thehackernews.com/2026/10/opencode-console-breach-may-have.html (通过 OpenCode 文章引用,2026 年 10 月 26 日)
- opencode-ai 的 npm 周下载量,截至 2026 年 10 月 22 日的一周为 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 star 数量,截至 2026 年 10 月 26 日为 221,765:https://api.github.com/repos/anomalyco/opencode (2026 年 10 月 26 日核查)