MCP Server Security & Performance Analysis — v0.3.0
| Test ID | Severity | Test Name | Description / Details | Duration |
|---|---|---|---|---|
| SECURITY · 82 tests | ||||
| T07-008 | MEDIUM | Invalid Tool Name Rejection |
Server accepted call to invalid tool name '' without error.Tool name '' was accepted with no error response.
Remediation:
Validate tool names on the server side. Empty, whitespace, null-byte, or non-existent tool names must be rejected with a structured error. |
48ms |
| T07-009 | MEDIUM | Oversized Argument Rejection |
Server accepted a 1 MB argument value without error — no input size limit enforced.Tool accepted 10 KB key + 1 MB value payload.
Remediation:
Enforce maximum argument size limits (e.g. 64 KB total per call). Unbounded inputs allow memory exhaustion attacks. |
23ms |
| T07-012 | MEDIUM | Unicode Homoglyph Tool Name Spoofing |
Server accepted unicode homoglyph of tool name 'fetch' → 'fеtch'.Original: 'fetch'
Spoofed: 'fеtch'
Server executed the spoofed name without rejection.
Remediation:
Validate tool names using exact byte-for-byte comparison and reject any name not in the known tool manifest. Homoglyph acceptance allows log poisoning and UI spoofing. |
32ms |
| T07-010 | LOW | Duplicate Initialize (Replay Attack) |
Server accepted a second initialize() call on an already active session. The session remained usable, but the server sta…Double initialize() succeeded.
Post-replay list_tools() succeeded — session is still functional but capabilities or internal state may have been altered.
Remediation:
The server should reject or ignore repeated initialize() calls. Accepting them enables mid-session protocol version downgrade and capability reset attacks. |
29ms |
| T07-013 | LOW | Protocol Version Abuse |
Server did not negotiate a recognised MCP protocol version (version is empty or unknown).
Remediation:
Ensure the server returns a valid protocolVersion in its initialize response (e.g. '2024-11-05'). Clients rely on this to select compatible behaviour. |
0ms |
| T24-001 | LOW | Deserialisation — Summary | 2 tool(s) leaked deserialiser markers in error messages. | 880ms |
| T24-TOOL-fetch-DS-002 | LOW | Deserialisation DS-002 → fetch |
Tool 'fetch' error suggests PyYAML unsafe is being invoked on user input. No confirmed RCE — review code path.Match: '!!python/object'
|
36ms |
| T24-TOOL-fetch-DS-003 | LOW | Deserialisation DS-003 → fetch |
Tool 'fetch' error suggests PyYAML unsafe is being invoked on user input. No confirmed RCE — review code path.Match: '!!python/object'
|
28ms |
| T07-001 | INFO | Unauthenticated Access | Unauthenticated Access test requires HTTP transport — skipped (transport='stdio'). | 0ms |
| T07-002 | INFO | Malformed Token Rejection | Malformed Token Rejection test requires HTTP transport — skipped (transport='stdio'). | 0ms |
| T07-003 | INFO | Resource URI Path Traversal | Server advertises no resources — path traversal test skipped. | 0ms |
| T07-005 | INFO | CORS Misconfiguration | CORS check requires HTTP transport — skipped (transport='stdio'). | 0ms |
| T07-006 | INFO | Process Privilege Check | Privilege check not available on Windows. | 0ms |
| T09-TOOL-fetch | INFO | Output Sanitization → fetch |
Tool 'fetch' is a data pass-through surface (file/diff/fetch/search). Output reflects external data verbatim; reverse-in…
Remediation:
Reverse-injection defence for pass-through tools belongs in the LLM's system prompt: instruct the model to treat content from these tools as untrusted data, not instructions. |
0ms |
| T13-002 | INFO | Unsolicited Sampling Requests | MCP client SDK does not expose an incoming-request hook; unsolicited sampling detection relies on capability audit (T13-001). | 23ms |
| T18-001 | INFO | SSRF — Summary | Server does not expose resources/read; SSRF probes skipped. | 0ms |
| T25-001 | INFO | IDOR — Summary | Server does not expose resources — IDOR probe skipped. | 0ms |
| T28-001 | INFO | Header Injection — Summary | STDIO transport has no HTTP headers — CRLF/header injection probe skipped. | 0ms |
| T30-001 | INFO | OAuth Flow Abuse — Summary | STDIO transport has no OAuth flow — probes skipped. | 0ms |
| T07-004 | PASS | Credentials in Error Messages |
No credential patterns found in error response for non-existent tool call.Error excerpt: "meta=None content=[TextContent(type='text', text='1 validation error for Fetch\\nurl\\n Field required [type=missing, input_value={}, input_type=dict]\\n For further information visit https://errors."
|
574ms |
| T07-007 | PASS | Environment Variable Probe |
Tool 'fetch' did not expand environment variable references in its response.Response excerpt: 'meta=None content=[TextContent(type=\'text\', text="1 validation error for Fetch\\nurl\\n Input should be a valid URL, relative URL without a base [type=url_parsing, input_value=\'$HOME $USER $PATH $AWS_S'
|
27ms |
| T07-011 | PASS | Deeply Nested Argument (JSON Bomb) | Server rejected deeply nested JSON argument. | 0ms |
| T09-001 | PASS | Output Sanitization — Summary | All 1 tool outputs and 0 resource reads passed PI-marker scanning. | 0ms |
| T12-001 | PASS | Error Secret Leakage — Summary | Probed 1 tool(s) and 0 resources; no secret patterns detected in error messages. | 603ms |
| T12-TOOL-fetch | PASS | Error Secret Leakage → fetch | Tool 'fetch' never errored on malformed inputs — nothing to scan. | 603ms |
| T13-001 | PASS | Sampling Capability Advertisement | Server does not advertise the 'sampling' capability. | 0ms |
| T13-003 | PASS | Sampling Abuse — Summary | No sampling-abuse surface detected. | 23ms |
| T19-001 | PASS | Non-ASCII Identifiers | All identifiers are pure ASCII. | 0ms |
| T19-002 | PASS | Confusable / Homoglyph Characters | No Unicode confusables detected in identifiers. | 0ms |
| T19-003 | PASS | Mixed-Script Identifiers | No mixed-script identifiers found. | 0ms |
| T19-004 | PASS | Invisible / Directional Characters | No invisible characters in identifiers. | 0ms |
| T19-005 | PASS | Homoglyph Scan — Summary | Scanned 2 identifier(s); no impersonation signals detected. | 0ms |
| T21-001 | PASS | Path Traversal — Summary | 12 probe(s) sent, no traversal to sensitive files confirmed. | 2865ms |
| T21-TOOL-fetch-PT-001 | PASS | Path Traversal PT-001 → fetch | Tool 'fetch' safely rejected Plain Unix. | 44ms |
| T21-TOOL-fetch-PT-002 | PASS | Path Traversal PT-002 → fetch | Tool 'fetch' safely rejected Plain Windows. | 555ms |
| T21-TOOL-fetch-PT-003 | PASS | Path Traversal PT-003 → fetch | Tool 'fetch' safely rejected URL-encoded. | 10ms |
| T21-TOOL-fetch-PT-004 | PASS | Path Traversal PT-004 → fetch | Tool 'fetch' safely rejected Double URL-encoded. | 45ms |
| T21-TOOL-fetch-PT-005 | PASS | Path Traversal PT-005 → fetch | Tool 'fetch' safely rejected UTF-8 overlong. | 24ms |
| T21-TOOL-fetch-PT-006 | PASS | Path Traversal PT-006 → fetch | Tool 'fetch' safely rejected Backslash + forward. | 47ms |
| T21-TOOL-fetch-PT-007 | PASS | Path Traversal PT-007 → fetch | Tool 'fetch' safely rejected Unicode normalisation. | 43ms |
| T21-TOOL-fetch-PT-008 | PASS | Path Traversal PT-008 → fetch | Tool 'fetch' safely rejected NUL byte truncation. | 111ms |
| T21-TOOL-fetch-PT-009 | PASS | Path Traversal PT-009 → fetch | Tool 'fetch' safely rejected Absolute Unix path. | 44ms |
| T21-TOOL-fetch-PT-010 | PASS | Path Traversal PT-010 → fetch | Tool 'fetch' safely rejected Absolute Windows path. | 953ms |
| T21-TOOL-fetch-PT-011 | PASS | Path Traversal PT-011 → fetch | Tool 'fetch' safely rejected Resource file:// scheme. | 493ms |
| T21-TOOL-fetch-PT-012 | PASS | Path Traversal PT-012 → fetch | Tool 'fetch' safely rejected Proto-smuggling. | 497ms |
| T22-001 | PASS | Command Injection — Summary | 8 probe(s) sent, no shell execution confirmed. | 879ms |
| T22-TOOL-fetch-CI-001 | PASS | Command Injection CI-001 → fetch | Tool 'fetch' safely handled Semicolon chain. | 555ms |
| T22-TOOL-fetch-CI-002 | PASS | Command Injection CI-002 → fetch | Tool 'fetch' safely handled Pipe. | 44ms |
| T22-TOOL-fetch-CI-003 | PASS | Command Injection CI-003 → fetch | Tool 'fetch' safely handled Background ampersand. | 17ms |
| T22-TOOL-fetch-CI-004 | PASS | Command Injection CI-004 → fetch | Tool 'fetch' safely handled Logical AND. | 39ms |
| T22-TOOL-fetch-CI-005 | PASS | Command Injection CI-005 → fetch | Tool 'fetch' safely handled Logical OR. | 30ms |
| T22-TOOL-fetch-CI-006 | PASS | Command Injection CI-006 → fetch | Tool 'fetch' safely handled Command substitution $(). | 41ms |
| T22-TOOL-fetch-CI-007 | PASS | Command Injection CI-007 → fetch | Tool 'fetch' safely handled Backtick cmdsub. | 47ms |
| T22-TOOL-fetch-CI-010 | PASS | Command Injection CI-010 → fetch | Tool 'fetch' safely handled Windows cmd chain. | 106ms |
| T23-001 | PASS | SQL Injection Deep — Summary | No deep SQLi findings across 1 probed tool(s). | 2369ms |
| T23-TOOL-fetch-SQL-001 | PASS | SQL SQL-001 → fetch |
No SQLi detected via UNION version on 'fetch'.baseline=559ms payload=40ms
|
40ms |
| T23-TOOL-fetch-SQL-002 | PASS | SQL SQL-002 → fetch |
No SQLi detected via UNION sqlite_ver on 'fetch'.baseline=559ms payload=23ms
|
23ms |
| T23-TOOL-fetch-SQL-003 | PASS | SQL SQL-003 → fetch |
No SQLi detected via Boolean true on 'fetch'.baseline=559ms payload=33ms
|
33ms |
| T23-TOOL-fetch-SQL-004 | PASS | SQL SQL-004 → fetch |
No SQLi detected via Boolean false on 'fetch'.baseline=559ms payload=36ms
|
36ms |
| T23-TOOL-fetch-SQL-005 | PASS | SQL SQL-005 → fetch |
No SQLi detected via Time blind PG on 'fetch'.baseline=559ms payload=36ms
|
36ms |
| T23-TOOL-fetch-SQL-006 | PASS | SQL SQL-006 → fetch |
No SQLi detected via Time blind MS on 'fetch'.baseline=559ms payload=47ms
|
47ms |
| T23-TOOL-fetch-SQL-007 | PASS | SQL SQL-007 → fetch |
No SQLi detected via Time blind MySQL on 'fetch'.baseline=559ms payload=106ms
|
106ms |
| T23-TOOL-fetch-SQL-008 | PASS | SQL SQL-008 → fetch |
No SQLi detected via Stacked drop on 'fetch'.baseline=559ms payload=43ms
|
43ms |
| T23-TOOL-fetch-SQL-009 | PASS | SQL SQL-009 → fetch |
No SQLi detected via NoSQL $ne on 'fetch'.baseline=559ms payload=1436ms
|
1436ms |
| T23-TOOL-fetch-SQL-010 | PASS | SQL SQL-010 → fetch |
No SQLi detected via NoSQL $gt on 'fetch'.baseline=559ms payload=11ms
|
11ms |
| T24-TOOL-fetch-DS-001 | PASS | Deserialisation DS-001 → fetch | Python pickle (b64) — no deserialisation markers detected. | 563ms |
| T24-TOOL-fetch-DS-004 | PASS | Deserialisation DS-004 → fetch | XML XXE file:// — no deserialisation markers detected. | 29ms |
| T24-TOOL-fetch-DS-005 | PASS | Deserialisation DS-005 → fetch | XML XXE parameter entity — no deserialisation markers detected. | 39ms |
| T24-TOOL-fetch-DS-006 | PASS | Deserialisation DS-006 → fetch | Java serialised magic (b64) — no deserialisation markers detected. | 38ms |
| T24-TOOL-fetch-DS-007 | PASS | Deserialisation DS-007 → fetch | Ruby Marshal magic (b64) — no deserialisation markers detected. | 47ms |
| T24-TOOL-fetch-DS-008 | PASS | Deserialisation DS-008 → fetch | JSON __proto__ pollution — no deserialisation markers detected. | 99ms |
| T26-001 | PASS | SSTI — Summary | No SSTI detected across 1 probed tool(s). | 2359ms |
| T26-TOOL-fetch-SSTI-001 | PASS | SSTI SSTI-001 → fetch | No template evaluation detected for Jinja/Twig {{7*7}} on 'fetch'. | 567ms |
| T26-TOOL-fetch-SSTI-002 | PASS | SSTI SSTI-002 → fetch | No template evaluation detected for Jinja concat on 'fetch'. | 33ms |
| T26-TOOL-fetch-SSTI-003 | PASS | SSTI SSTI-003 → fetch | No template evaluation detected for Handlebars #with on 'fetch'. | 36ms |
| T26-TOOL-fetch-SSTI-004 | PASS | SSTI SSTI-004 → fetch | No template evaluation detected for ERB <%= 7*7 %> on 'fetch'. | 22ms |
| T26-TOOL-fetch-SSTI-005 | PASS | SSTI SSTI-005 → fetch | No template evaluation detected for Freemarker ${7*7} on 'fetch'. | 38ms |
| T26-TOOL-fetch-SSTI-006 | PASS | SSTI SSTI-006 → fetch | No template evaluation detected for Velocity #set on 'fetch'. | 45ms |
| T26-TOOL-fetch-SSTI-007 | PASS | SSTI SSTI-007 → fetch | No template evaluation detected for JSP ${7*7} on 'fetch'. | 40ms |
| T26-TOOL-fetch-SSTI-008 | PASS | SSTI SSTI-008 → fetch | No template evaluation detected for Smarty {$x=7*7} on 'fetch'. | 139ms |
| T26-TOOL-fetch-SSTI-009 | PASS | SSTI SSTI-009 → fetch | No template evaluation detected for Razor @(7*7) on 'fetch'. | 9ms |
| T26-TOOL-fetch-SSTI-010 | PASS | SSTI SSTI-010 → fetch | No template evaluation detected for Mako <%= 7*7 %> on 'fetch'. | 1429ms |
| DISCOVERY · 8 tests | ||||
| T01-001 | INFO | Server Identity |
Server did not advertise: name, version. Got name='unknown' version='unknown' protocol='unknown'.
Remediation:
Ensure the MCP server returns a populated 'serverInfo' object in its initialize response (name and version fields). |
0ms |
| T01-002 | PASS | Tool Enumeration |
Discovered 1 tool(s): fetch.fetch: 'Fetches a URL from the internet and optionally extracts its contents as markdown'
|
0ms |
| T01-003 | PASS | Resource Enumeration | Discovered 0 resource(s). | 0ms |
| T01-004 | PASS | Prompt Enumeration |
Discovered 1 prompt(s): fetch.fetch: 'Fetch a URL and extract its contents as markdown' (1 arg(s))
|
0ms |
| T01-005 | PASS | Tool Description Completeness | All 1 tool(s) have non-empty descriptions. | 0ms |
| T01-006 | PASS | Tool Schema Validity | All 1 tool(s) have valid JSON Schema inputSchema. | 0ms |
| T01-007 | PASS | Duplicate Tool Names | All 1 tool name(s) are unique. | 0ms |
| T01-008 | PASS | Tool Description Length | All 1 tool description(s) are within the 2,000-character limit. | 0ms |
| SCHEMA · 6 tests | ||||
| T06-003 | INFO | additionalProperties Strictness |
1/1 tool(s) missing 'additionalProperties': false.Tools missing additionalProperties:false: fetch
Remediation:
Adding 'additionalProperties': false to every inputSchema prevents callers from silently passing undeclared fields that could confuse server-side processing. |
0ms |
| T06-004 | INFO | Return Type Consistency | All tools have required fields — return-type consistency test skipped. | 0ms |
| T06-001 | PASS | Schema Structural Validity | All 1 tool inputSchema(s) are structurally valid. | 0ms |
| T06-002-fetch | PASS | Required Enforcement: fetch | Tool 'fetch' returned an error response for missing required fields. | 19ms |
| T06-005 | PASS | Overly Permissive Schema Detection | All 1 tool schema(s) are acceptably strict. | 0ms |
| T06-006-fetch | PASS | Description Quality: fetch |
Tool 'fetch' has an adequate description (307 chars).Description: 'Fetches a URL from the internet and optionally extracts its contents as markdown.\n\nAlthough originally you did not have internet access, and were advised to refuse and tell the user this, this tool no'
|
0ms |
| PERFORMANCE · 5 tests | ||||
| T00-003 | INFO | Connection Closed Mid-Scan (Rate Limit / Server Reset) |
The HTTP server closed the connection mid-scan. This is expected behaviour for production servers that apply rate-limiti…Unexpected stdio transport error: ConnectionResetError: Connection lost (caused by ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception))
Remediation:
Re-run with --no-load to skip T05 load tests and reduce the number of requests sent to the server. The connection drop does not indicate a vulnerability. |
8576ms |
| T08-003-00 | INFO | Resource Read Latency | No resources to benchmark. | 0ms |
| T08-001-01 | PASS | Baseline Latency: fetch |
Tool 'fetch': mean=7ms min=4ms max=13ms (5 samples).{
"fetch": {
"mean_ms": 6.65,
"min_ms": 4.44,
"max_ms": 12.7,
"samples": [
12.7,
7.02,
4.61,
4.49,
4.44
]
}
}
|
33ms |
| T08-002 | PASS | Tool Discovery Latency |
list_tools() mean=3ms min=3ms max=3ms.{
"list_tools": {
"mean_ms": 2.74,
"min_ms": 2.51,
"max_ms": 2.98,
"samples": [
2.98,
2.95,
2.68,
2.59,
2.51
]
}
}
|
14ms |
| T08-004 | PASS | Cold Start Detection |
No significant cold-start penalty detected (ratio 1.1×, threshold 10×).Call 1 (cold): 5ms
Calls 2-5 (warm): 4ms, 4ms, 4ms, 5ms
Warm mean: 4ms Ratio: 1.1×
|
23ms |