-
Notifications
You must be signed in to change notification settings - Fork 16
Description
Security Vulnerability Report
Reporter: @bitox76
Severity: High / Medium
Affected Version: Latest (main branch as of Feb 2026)
Overview
During a security audit of MCP-Workspace-Server, I identified 3 verified security vulnerabilities. The most impactful are: (1) Server-Side Request Forgery (SSRF) in the web crawl tool allowing access to internal services and cloud metadata, and (2) missing authentication on User API endpoints enabling unauthorized file access.
Vulnerability 1: Server-Side Request Forgery (SSRF) in Web Crawl Tool
CWE-918 | CVSS 3.1: 6.5 Medium-High
File: mcp_filesystem/tools/web_crawl_tools.py — _validate_url() function (lines ~63-68)
Description: The URL validation only checks for http/https scheme and non-empty netloc, but does NOT block:
- Private/internal IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
- Loopback addresses (127.0.0.0/8)
- Link-local addresses (169.254.0.0/16)
- Cloud metadata endpoints (169.254.169.254)
- Known internal hostnames (localhost, metadata.google.internal, etc.)
Vulnerable Code:
def _validate_url(url: str) -> Optional[str]:
parsed = urlparse(url)
if parsed.scheme not in ("http", "https"):
return "仅支持 http/https URL"
if not parsed.netloc:
return "URL 缺少域名"
return None # <-- No private IP or internal host blockingAfter validation, the URL is passed directly to crawler.arun(url=url).
Proof of Concept:
{
"tool": "crawl_url",
"arguments": {
"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
}
}On AWS/GCP/Azure, this retrieves cloud instance credentials and metadata.
{
"tool": "crawl_url",
"arguments": { "url": "http://192.168.1.1/admin" }
}This accesses internal network services that should not be reachable from the server.
Suggested Fix:
import ipaddress
import socket
BLOCKED_NETWORKS = [
ipaddress.ip_network("10.0.0.0/8"),
ipaddress.ip_network("172.16.0.0/12"),
ipaddress.ip_network("192.168.0.0/16"),
ipaddress.ip_network("127.0.0.0/8"),
ipaddress.ip_network("169.254.0.0/16"),
ipaddress.ip_network("::1/128"),
]
def _validate_url(url: str) -> Optional[str]:
parsed = urlparse(url)
if parsed.scheme not in ("http", "https"):
return "仅支持 http/https URL"
if not parsed.netloc:
return "URL 缺少域名"
# Resolve hostname and check against blocked networks
hostname = parsed.hostname
if hostname in ("localhost", "metadata.google.internal"):
return "Blocked internal hostname"
try:
ip = ipaddress.ip_address(socket.gethostbyname(hostname))
for network in BLOCKED_NETWORKS:
if ip in network:
return f"Blocked private/internal IP: {ip}"
except (socket.gaierror, ValueError):
pass
return NoneVulnerability 2: Missing Authentication on User API Endpoints
CWE-306 | CVSS 3.1: 7.5 High
File: mcp_filesystem/http_routes.py — multiple User API handlers (~lines 390-760)
Description: User API endpoints (user_workspace_tree, api_workspace_file_download, api_workspace_file_preview, etc.) rely solely on client-supplied user_id and chat_id from query parameters or headers, with NO server-side authentication or authorization.
Vulnerable Pattern:
user_id = request.query_params.get("user_id") or request.headers.get("x-user-id")
chat_id = request.query_params.get("chat_id") or request.headers.get("x-chat-id")
# No authentication check!
workspace_name = get_workspace_name(user_id, chat_id) # format: {user_id}_{chat_id}The workspace naming scheme {user_id}_{chat_id} is trivially guessable/enumerable.
PoC:
# Access victim's workspace files
curl "http://target:18089/api/user/workspace/tree?user_id=victim&chat_id=abc123"
curl "http://target:18089/api/workspace/file/download?user_id=victim&chat_id=abc123&file_path=secret.txt"Vulnerability 3: Unreachable Code Bug in Directory Tree (Logic Error)
CWE-561 | Severity: Low
File: mcp_filesystem/advanced.py — _build_tree_node() (lines 193-221)
The try block is incorrectly indented under a continue statement, making it unreachable when a pattern filter is used. This causes directory_tree with a pattern argument to return empty/incorrect results.
Recommendations
- P0: Add SSRF protection by blocking private IPs and cloud metadata endpoints in the URL validator.
- P0: Add authentication and authorization for all User API endpoints.
- P1: Fix indentation bug in
advanced.py.
Responsible Disclosure: I am reporting this in good faith to improve the project's security. If you have a preferred private security reporting channel, please let me know. I am happy to coordinate on fixes and provide additional details.
I would appreciate if the maintainers could request CVE identifiers for the SSRF and Missing Auth vulnerabilities. Credit: @bitox76