reap / range
reap-range
A deliberately vulnerable MCP server, and a correctly configured mirror of it, for practising agent recon and checking that a scanner’s silence means what it says.
Quick start
git clone https://github.com/hackwither/reap-range && cd reap-range docker build -t reap-range . docker run --rm -p 8080:8080 -p 8090:8090 reap-range
| target | port | paths | posture |
|---|---|---|---|
| bad | 8080 | /mcp, /mcp/gated | Deliberately insecure |
| good | 8090 | /mcp | Correctly configured mirror |
No Docker? python3 server.py runs it with the standard library only.
Three scans
Open. The insecure target lights up most checks in one scan.
14 of 17 checks match
reap -t http://localhost:8080/mcp --authorized
REAP / AI AGENT RECON ──────────────────────────────────────────────────────────────────── v0.1.2-dev+ad8ce39 TARGET http://localhost:8080/mcp ::1 • MCP 2025-06-18 • http-streamable • CONFIRMED Agent reap-range 0.1.0 Edge Werkzeug/3.0 Python/3.12.3 Discovery mcp-http-streamable • high confidence Auth open • enumeration answered without credentials Surface 3 tools • 1 resources • 1 prompts FINDINGS 15 matched • use -v for full evidence HIGH mcp-unauth-tools-list HIGH CONFIDENCE MCP tool listing accessible without authentication tools/list returned 3 tool(s) to an unauthenticated caller: exec_shell, search_tools, run_tool Evidence POST http://localhost:8080/mcp → 200 • application/json • 783 B OWASP ASI02: Tool Misuse and Exploitation, ASI03: Identity and Privilege Abuse Fix Require authentication before tools/list, or scope the response so anonymous callers see nothing. HIGH mcp-host-header-validation HIGH CONFIDENCE MCP accepted initialize with a mismatched Host header The server processed an initialize request even though the Host header was set to "host-header-validation.invalid", so it does not validate the requested host name before handling MCP traffic. This is the condition DNS-rebinding protection prevents; it is rated high only for loopback endpoints, where a browser-driven rebinding attack reaches a local agent directly. Evidence POST http://localhost:8080/mcp → 200 • application/json • 329 B OWASP ASI03: Identity and Privilege Abuse Fix Validate the Host header or equivalent request target before accepting MCP requests, and refuse requests whose host name does not match the configured endpoint. HIGH mcp-dynamic-dispatch MEDIUM CONFIDENCE Enumerated MCP tool surface is likely incomplete (dynamic dispatch detected) Discovery tool(s) search_tools and executor tool(s) run_tool were detected. This indicates tools/list likely undercounts the real capability surface because callable tools can be reached through search + dispatch. Evidence POST http://localhost:8080/mcp → 200 • application/json • 783 B OWASP ASI09: Human-Agent Trust Exploitation Fix Expose a complete dispatchable tool manifest or provide a discoverable read-only tool inventory (for example, an extended list endpoint) so downstream security tooling can account for the full surface. HIGH http-cors-wildcard Permissive CORS policy on agent endpoint Server returns Access-Control-Allow-Origin: * — any web origin can call this endpoint from a browser context. Combined with Access-Control-Allow-Credentials: true, this allows credentialed cross-origin requests, which browsers should normally block. OWASP ASI03: Identity and Privilege Abuse Fix Scope Access-Control-Allow-Origin to known first-party origins; never reflect an arbitrary Origin, and never combine * with credentialed requests. MED mcp-redirect-uri-laxity MEDIUM CONFIDENCE OAuth redirect URI registration appears overly broad The discovered OAuth metadata includes redirect URIs that are broad or wildcarded, which increases the risk of confused-deputy or open redirect abuse. Evidence GET http://localhost:8080/.well-known/oauth-authorization-server → 200 OWASP ASI03: Identity and Privilege Abuse Fix Restrict registered redirect URIs to exact allowed origins and paths, and avoid wildcards or overly permissive URL patterns. MED mcp-session-id-entropy HIGH CONFIDENCE MCP session ID entropy looks weak or predictable The MCP session ID returned by the server appears to have low entropy or a predictable format: session ID is shorter than 16 characters, estimated entropy is low (36 bits) OWASP ASI03: Identity and Privilege Abuse Fix Use a cryptographically random, high-entropy session identifier for MCP sessions and avoid sequential or human-readable formats. MED transport-plaintext Agent endpoint served over plaintext HTTP Target URL uses http:// rather than https://. Tool calls, arguments, and any auth tokens are visible to on-path observers. OWASP ASI07: Insecure Inter-Agent Communication Fix Serve agent endpoints over TLS only; redirect or refuse plaintext connections. MED mcp-tmpl-high-risk-tool-names HIGH CONFIDENCE Tool list includes names suggesting code execution or filesystem access The tool list (requested with credentials, if any were supplied) includes a tool name matching patterns associated with code-execution or raw-filesystem primitives. This is a triage signal for closer review; verify the tool's actual capabilities and authorization model. Evidence POST http://localhost:8080/mcp → 200 • application/json • 783 B OWASP ASI02: Tool Misuse and Exploitation, ASI05: Unexpected Code Execution (RCE) Fix Review tool capabilities in context. If the tool performs code execution or unrestricted filesystem access, scope it behind explicit, auditable authorization separate from general tool listing. Consider narrower alternatives. LOW mcp-oauth-metadata-posture HIGH CONFIDENCE Published OAuth metadata does not advertise PKCE OAuth metadata was published at /.well-known/oauth-authorization-server, but it does not advertise PKCE (code_challenge_methods_supported) support. Evidence GET http://localhost:8080/.well-known/oauth-authorization-server → 200 • application/json OWASP ASI03: Identity and Privilege Abuse Fix Advertise PKCE support (code_challenge_methods_supported: ["S256"]) in published OAuth authorization-server metadata. LOW mcp-instructions-exposure MEDIUM CONFIDENCE MCP handshake returns lengthy or sensitive-flavored instructions The initialize response's 'instructions' field is long and/or contains language patterns (secrecy directives, 'internal', credential-related terms) worth a human review to confirm it isn't leaking operational or internal detail to any caller. Evidence POST http://localhost:8080/mcp → 200 • application/json • 329 B OWASP ASI09: Human-Agent Trust Exploitation Fix Keep client-facing instructions limited to usage guidance; keep anything sensitive out of fields returned pre-authentication. LOW mcp-resources-prompts-exposure-resources-list HIGH CONFIDENCE Unauthenticated resources/list returns 1 item(s) resources/list succeeded without credentials and returned 1 item(s) to an anonymous caller. Evidence POST http://localhost:8080/mcp → 200 • application/json • 101 B OWASP ASI02: Tool Misuse and Exploitation Fix Gate resource/prompt listings behind authentication if their contents aren't meant to be public. LOW mcp-resources-prompts-exposure-prompts-list HIGH CONFIDENCE Unauthenticated prompts/list returns 1 item(s) prompts/list succeeded without credentials and returned 1 item(s) to an anonymous caller. Evidence POST http://localhost:8080/mcp → 200 • application/json • 117 B OWASP ASI02: Tool Misuse and Exploitation Fix Gate resource/prompt listings behind authentication if their contents aren't meant to be public. LOW http-rate-limit-absence No standard rate-limit headers observed The endpoint answered requests but sent no standard rate-limit response headers. This is a reconnaissance signal that the service may not be advertising rate limiting to clients; it is not proof that no limiting exists. OWASP ASI08: Cascading Failures Fix Expose standard rate-limit headers such as Retry-After, RateLimit-Remaining, and RateLimit-Limit, or document the expected client behavior when limits are reached. INFO mcp-tool-capability-surface HIGH CONFIDENCE Tool capability inventory (3 tools) Full tool surface exposed by this endpoint, for asset-inventory and diffing purposes. Evidence POST http://localhost:8080/mcp → 200 • application/json • 783 B OWASP ASI09: Human-Agent Trust Exploitation INFO mcp-tmpl-server-header-fingerprint MEDIUM CONFIDENCE Server response header discloses backend/edge software The response includes a Server or X-Powered-By header identifying backend software that appears to be the origin application, not a CDN/edge layer (which is already surfaced separately in the target fingerprint's Edge line). Not a vulnerability by itself, but useful fingerprinting context worth trimming in production. Evidence POST http://localhost:8080/mcp → 200 • application/json • 783 B OWASP ASI09: Human-Agent Trust Exploitation Fix Suppress or genericize identifying response headers in production deployments where they name the origin application. POSTURE HIGH RISK 17 checks • 14 matched • 1 clean • 2 skipped • 28ms 4 high · 4 med · 5 low · 2 info · 0 error
Auth-gated. An endpoint that correctly requires credentials is a recon result, not a tool failure: REAP reports auth-gated and exits 0. This is also the only path where the bearer-challenge check can fire.
reap -t http://localhost:8080/mcp/gated --authorized
REAP / AI AGENT RECON ──────────────────────────────────────────────────────────────────── v0.1.2-dev+ad8ce39 TARGET http://localhost:8080/mcp/gated ::1 • MCP • http-streamable • CONFIRMED (AUTH-GATED) Edge Werkzeug/3.0 Python/3.12.3 Discovery mcp-http-streamable-version-mismatch-auth-gated • low confidence Auth auth-gated • live, but requires credentials to enumerate ⓘ AUTH REQUIRED initialize requires auth: HTTP 401 (application/problem+json, JSON-RPC error envelope) FINDINGS 7 matched • use -v for full evidence MED mcp-oauth-bearer-challenge-missing HIGH CONFIDENCE Protected resource does not send a Bearer WWW-Authenticate challenge An unauthenticated tools/list request returned 401, but its WWW-Authenticate header did not include a Bearer challenge (got ""). Evidence POST http://localhost:8080/mcp/gated → 401 • application/json • 92 B OWASP ASI03: Identity and Privilege Abuse Fix Send a WWW-Authenticate: Bearer challenge (optionally with a resource_metadata parameter per RFC 9728) on unauthenticated requests to protected MCP endpoints. MED mcp-redirect-uri-laxity MEDIUM CONFIDENCE OAuth redirect URI registration appears overly broad The discovered OAuth metadata includes redirect URIs that are broad or wildcarded, which increases the risk of confused-deputy or open redirect abuse. Evidence GET http://localhost:8080/.well-known/oauth-authorization-server → 200 OWASP ASI03: Identity and Privilege Abuse Fix Restrict registered redirect URIs to exact allowed origins and paths, and avoid wildcards or overly permissive URL patterns. MED transport-plaintext Agent endpoint served over plaintext HTTP Target URL uses http:// rather than https://. Tool calls, arguments, and any auth tokens are visible to on-path observers. OWASP ASI07: Insecure Inter-Agent Communication Fix Serve agent endpoints over TLS only; redirect or refuse plaintext connections. LOW mcp-oauth-metadata-posture HIGH CONFIDENCE Published OAuth metadata does not advertise PKCE OAuth metadata was published at /.well-known/oauth-authorization-server, but it does not advertise PKCE (code_challenge_methods_supported) support. Evidence GET http://localhost:8080/.well-known/oauth-authorization-server → 200 • application/json OWASP ASI03: Identity and Privilege Abuse Fix Advertise PKCE support (code_challenge_methods_supported: ["S256"]) in published OAuth authorization-server metadata. LOW http-rate-limit-absence No standard rate-limit headers observed The endpoint answered requests but sent no standard rate-limit response headers. This is a reconnaissance signal that the service may not be advertising rate limiting to clients; it is not proof that no limiting exists. OWASP ASI08: Cascading Failures Fix Expose standard rate-limit headers such as Retry-After, RateLimit-Remaining, and RateLimit-Limit, or document the expected client behavior when limits are reached. INFO mcp-enumeration-blocked HIGH CONFIDENCE Tool enumeration blocked by authentication tools/list returned 401 without credentials — the server correctly gates enumeration behind authentication, so no tool inventory is available from this vantage point. Evidence POST http://localhost:8080/mcp/gated → 401 • application/json • 92 B OWASP ASI09: Human-Agent Trust Exploitation INFO mcp-tmpl-server-header-fingerprint MEDIUM CONFIDENCE Server response header discloses backend/edge software The response includes a Server or X-Powered-By header identifying backend software that appears to be the origin application, not a CDN/edge layer (which is already surfaced separately in the target fingerprint's Edge line). Not a vulnerability by itself, but useful fingerprinting context worth trimming in production. Evidence POST http://localhost:8080/mcp/gated → 401 • application/json • 92 B OWASP ASI09: Human-Agent Trust Exploitation Fix Suppress or genericize identifying response headers in production deployments where they name the origin application. POSTURE MEDIUM RISK 17 checks • 6 matched • 8 clean • 3 skipped • 11ms 0 high · 3 med · 2 low · 2 info · 0 error
Correct. The mirror shows the false-positive floor: everything is silent except one expected, informational finding. transport-plaintext is excluded because the range is plain HTTP.
reap -t http://localhost:8090/mcp --authorized --exclude transport-plaintext
REAP / AI AGENT RECON ──────────────────────────────────────────────────────────────────── v0.1.2-dev+ad8ce39 TARGET http://localhost:8090/mcp ::1 • MCP 2025-06-18 • http-streamable • CONFIRMED Agent reap-range 0.1.0 Discovery mcp-http-streamable • high confidence Auth auth-gated • live, but requires credentials to enumerate FINDINGS 1 matched • use -v for full evidence INFO mcp-enumeration-blocked HIGH CONFIDENCE Tool enumeration blocked by authentication tools/list returned 401 without credentials — the server correctly gates enumeration behind authentication, so no tool inventory is available from this vantage point. Evidence POST http://localhost:8090/mcp → 401 • application/json • 92 B OWASP ASI09: Human-Agent Trust Exploitation POSTURE INFORMATIONAL 16 checks • 1 matched • 13 clean • 2 skipped • 14ms 0 high · 0 med · 0 low · 1 info · 0 error
Unedited output of reap 0.1.2-dev+ad8ce39 against a local reap-range.
What each target does
Every rule page lists how the insecure and correct targets behave for that check, for example mcp-host-header-validation. The full feature table and known limitations are in the reap-range README.