T09 · Insecure Skill Coding Practices
Error
- Location
- references/error-handling.md:64
- Finding
- Caller-Controlled URL Fetch Enables Server-Side Request Forgery## Vulnerability Details **File Location**: `references/error-handling.md`, lines 64-81 **Vulnerability Type**: Server-Side Request Forgery (SSRF) **Risk Level**: High **Vulnerable code:** ```typescript async function fetchHandler({ url }: { url: string }) { try { const response = await fetch(url); if (!response.ok) { return { isError: true, content: [{ type: "text", text: `Upstream returned ${response.status}: ${response.statusText}. Try a different URL or check if the service is available.` }], }; } const data = await response.json(); return { content: [{ type: "text", text: JSON.stringify(data) }] }; } catch (err) { return { isError: true, content: [{ type: "text", text: `Network error fetching ${url}: ${err instanceof Error ? err.message : "unknown"}. The service may be down.` }], }; } } ``` ### Technical Analysis The example passes a caller-controlled `url` directly to `fetch()` and returns the resulting response to the caller. It does not restrict URL schemes or destinations, reject private and link-local addresses, validate redirects, protect against DNS rebinding, or limit response size. If copied into an MCP server, this creates an SSRF primitive. An attacker could request loopback addresses, private network ranges, internal administrative services, or cloud instance metadata endpoints. Redirect-based and DNS time-of-check/time-of-use techniques could bypass superficial validation added by downstream implementers. The project contains appropriate SSRF mitigation guidance elsewhere, including private-address blocking in `references/security-auth.md`, but the directly reusable example does not apply or reference those controls. ### Attack Path 1. A server author copies the example into a remotely accessible MCP tool. 2. An attacker invokes the tool with an internal URL, such as a loopback service, private network e ...[truncated 891 chars]
- Remediation
- ## Remediation Suggestions - Prefer accepting a resource identifier rather than an arbitrary URL. - If arbitrary URLs are required, restrict schemes to HTTPS and enforce an explicit hostname or domain allowlist. - Resolve the hostname before connecting and reject loopback, private, link-local, multicast, reserved, and unspecified IPv4 and IPv6 ranges. - Pin the validated DNS result for the connection to prevent DNS rebinding and TOCTOU attacks. - Disable automatic redirects or validate every redirect target using the same scheme, hostname, and resolved-address policy. - Explicitly block cloud metadata ranges, including `169.254.0.0/16`. - Apply connection, read, and total-request timeouts. - Stream responses through a strict byte limit rather than calling `response.json()` on an unbounded body. - Restrict accepted content types and avoid returning sensitive upstream headers or verbose network errors. - Route outbound requests through a policy-enforcing egress proxy where possible. - Add tests covering loopback, private IPv4, private IPv6, encoded IP addresses, redirect-to-private-host, and DNS-rebinding cases.
