CVE-2025-6514: How Old Bugs Hijacked the AI Hype
- September 15, 2025
- 7 mins
- Analysis
TL’DR
CVE-2025-6514 is a throwback command-injection bug living inside the Model Context Protocol (MCP) ecosystem. Point an MCP-aware client at a booby-trapped server and the attacker wins remote code execution. It is a bellwether for the ship-fast AI tooling wave.
Risk Scorecard
| Attribute | Detail |
|---|---|
| CVE | CVE-2025-6514 |
| Severity | 9.6 (Critical) |
| Affected | mcp-remote 0.0.5 → 0.1.15 |
| Fixed | 0.1.16 |
| Root Cause | Unvalidated authorization_endpoint passed to the open npm package |
| Who | JFrog Security Research |
Why This One Matters
mcp-remote goes straight for builders. It is glued into developer workflows, so a compromise lands on a workstation full of source, model weights, tokens, and production credentials.
The root cause is a missed URL validation check. A brand-new AI protocol is reopening a CWE-78 class that should be muscle memory by now.
The blast radius is supply-chain sized. Registry stats show hundreds of thousands of downloads, and the proxy is already embedded downstream. One rushed update pushes the bug into everything that depends on it.

MCP in 200 Words
The Model Context Protocol (MCP) arrived in late 2024 to give large language models controlled access to live data. It defines transports so an AI assistant can call APIs, query databases, or trigger automations in real time while respecting user-driven allow lists.
Two transports matter here:
- Local (STDIO): client and MCP server live on the same machine.
- Remote (HTTP): client speaks across the network.
Claude Desktop and similar clients only ship local transport support. Enter mcp-remote: a shim that takes Claude’s STDIO chatter, wraps it in HTTP, and handles OAuth-style auth flows on behalf of the user. That convenience is exactly where things snap.
Trusted Proxy, Untrusted Endpoint
mcp-remote sits between a local AI assistant and whatever MCP server you point it at. It translates STDIO traffic into HTTP, fetches OAuth metadata from /.well-known/oauth-authorization-server, and launches a browser window for the authorization_endpoint it receives. The design assumes the remote server is honest. When it is not, a poisoned authorization_endpoint becomes attacker-controlled data that the proxy dutifully funnels into open(...).
Exploit Chain (Visualise This as a Timeline)
Step 1: Setup
The victim points their assistant at mcp-remote://attacker. From then on the attacker owns the server endpoint.
Step 2: Handshake
The proxy reaches out and receives a polite 401 Unauthorized, which is a normal OAuth cue to keep going.
Step 3: Metadata Pull
mcp-remote fetches /.well-known/oauth-authorization-server and parses the metadata blob it receives.
Step 4: Payload Delivery
The metadata swaps in a hostile value for authorization_endpoint, usually a file:// URL or invented scheme. There is no validation or allow list, so the value flows straight through.
Step 5: Execution
open(malicious_string) fires. On Windows, PowerShell runs whatever command the attacker tucked inside. On macOS/Linux, the system launches the specified executable.
Pocket version: “One JSON field → remote shell.”
Payload Anatomy
- Trigger: Any OAuth challenge (trivial for an attacker to return).
- Field:
authorization_endpoint. - Value:
file:///c:/windows/system32/calc.exeora:$(cmd.exe /c whoami > c:\\temp\\pwned.txt). - Why it sticks:
opentrusts the string and invokes PowerShell (Windows) oropen/xdg-open(macOS/Linux) without sanitising.
Windows: OAuth → PowerShell in Two Frames
# Delivered inside authorization_endpoint
a:$(cmd.exe /c powershell -EncodedCommand SQBFAFgAIAAiY2FsYy5leGUi)
- The fake scheme (
a:) bypasses URL encoding insideopen. - PowerShell runs with the permissions of the user launching the LLM client.
- You get full command injection, parameter support, and file system access.
macOS & Linux: More Work, Still Dangerous
- The proxy spawns
/usr/bin/open(macOS) orxdg-open(Linux). file://URLs still launch local applications (think:file:///usr/bin/osascript).- Argument control is limited because everything after the path is treated as query parameters, but it is a foothold.
- With further research, chaining native binaries can still lead to arbitrary code execution.