MCP Security
11 rules for MCP server security — 9 regex-based + 2 KERN IR structural rules. TypeScript and Python. Verified 9/9 against the appsecco vulnerable MCP servers lab.
Usage
# Scan an MCP server file
kern review --mcp server.ts
# Auto-detect also works
kern review src/ --recursive
# JSON output for CI
kern review --mcp server.ts --jsonRules
All rules are mapped to CWE identifiers and the OWASP MCP Top 10.
| Rule | What it catches | CWE | OWASP MCP |
|---|---|---|---|
mcp-command-injection | exec/eval in tool handlers with user params | CWE-77 | MCP04 |
mcp-path-traversal | File ops without path containment | CWE-22 | MCP03 |
mcp-tool-poisoning | Hidden instructions in tool descriptions | CWE-1427 | MCP02 |
mcp-secrets-exposure | Hardcoded keys/tokens + base64 obfuscation | CWE-798 | MCP01 |
mcp-unsanitized-response | Raw external data in tool responses | CWE-1427 | MCP05 |
mcp-missing-validation | Tool params used without schema validation | CWE-20 | MCP04 |
mcp-missing-auth | Remote HTTP/SSE server without auth | CWE-306 | MCP04 |
mcp-typosquatting | Package/server name similar to known MCP servers | — | MCP06 |
mcp-data-injection | Hidden injection markers in string literals | CWE-1427 | MCP02 |
mcp-ir-unguarded-effect | KERN IR: action has effects without guards | — | structural |
mcp-ir-low-confidence | KERN IR: action confidence <= 0.3 | — | structural |
Example
// Vulnerable MCP server
server.tool('run', 'Run command', {}, async (params) => {
execSync(`${params.cmd}`);
});
// kern review output:
// ! mcp-command-injection: Shell command execution
// in MCP tool handler [confidence: 0.95]
// ! mcp-ir-unguarded-effect: action "run" has
// shell-exec effect without any guard [confidence: 0.90]How it compares
KERN scans the code that makes the server dangerous. mcp-scan and Proximity check running servers. Use both.
| Capability | kern review | mcp-scan | Proximity |
|---|---|---|---|
| Analysis type | Static (source code) | Dynamic (running server) | Dynamic (running server) |
| Languages | TypeScript + Python | Any (protocol-level) | Any (protocol-level) |
| Prompt injection | Yes (code + data) | Yes (tool descriptions) | Yes (tool descriptions) |
| Command injection | Yes (taint + IR) | No | No |
| Path traversal | Yes (AST + IR) | No | No |
| Secrets detection | Yes (pattern + base64) | No | No |
| Auth checks | Yes (middleware) | No | No |
| Structural analysis | Yes (KERN IR) | No | No |
| Requires running server | No | Yes | Yes |
| Confidence scoring | Yes (0.70–0.95) | No | No |
Benchmark
Verified against the appsecco/vulnerable-mcp-servers-lab — 9 intentionally vulnerable MCP servers covering OWASP MCP Top 10 scenarios.
- Score: 9/9 (8 direct hits + 1 indirect)
- Indirect: outdated-packages — dependency scanning, not our domain
- Tests: 75 test cases in packages/review-mcp/tests/