T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/safe-web.py:71
- Finding
- Unrestricted URL Fetching Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/safe-web.py`, lines 71 and 182–184 **Vulnerability Type**: Server-Side Request Forgery (SSRF) **Risk Level**: High ### Vulnerable Code ```python response = requests.get(url, headers=headers, timeout=timeout, allow_redirects=True) ``` ```python # Validate URL parsed = urlparse(args.url) if not parsed.scheme or not parsed.netloc: print(f"Error: Invalid URL: {args.url}", file=sys.stderr) sys.exit(1) ``` ### Technical Analysis The URL validation only verifies that the supplied value has a scheme and network location. It does not: - Restrict the scheme explicitly to HTTP or HTTPS. - Reject loopback, private, link-local, reserved, multicast, or unspecified IP addresses. - Resolve hostnames and validate every resulting IP address. - Protect against DNS rebinding. - Validate redirect destinations. - Limit the size of downloaded responses. The URL is subsequently passed to `requests.get()` with `allow_redirects=True`. Consequently, a caller can instruct the Skill to connect to an internal service directly or use a public endpoint that redirects to an internal address. PromptGuard scans the returned text for prompt-injection patterns, but it is not an SSRF defense. Internal data that does not trigger the prompt-injection threshold can still be printed, returned as JSON, or written to a caller-selected output file. ### Attack Path 1. An attacker causes the Skill to invoke the fetch command with a URL targeting an internal resource, such as: - A loopback service. - A private-network administration interface. - A cloud instance metadata endpoint. - A public URL that redirects to one of these targets. 2. The code confirms only that the URL contains a scheme and network location. 3. `requests.get()` connects to the target and follows redirects automatically. 4. The response body is parsed by BeautifulSoup and scanned by PromptGuard. 5. If the response does not meet the prompt-injection ...[truncated 748 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Permit only explicit `http` and `https` schemes. 2. Reject URLs containing embedded credentials or ambiguous host representations. 3. Resolve the hostname before connecting and reject every address in loopback, private, link-local, reserved, multicast, or unspecified ranges for both IPv4 and IPv6. 4. Disable automatic redirects or validate each redirect destination using the same scheme and IP-address policy. 5. Protect against DNS rebinding by ensuring the validated destination is the address used for the connection. 6. Consider an allowlist of domains when the Skill is used in a controlled environment. 7. Apply maximum response-size and redirect-count limits. 8. Apply outbound firewall or proxy rules so the process cannot reach cloud metadata endpoints or internal management networks. 9. Add automated tests covering direct private addresses, IPv6 loopback, alternate IP representations, DNS names resolving to private addresses, and public-to-private redirects. ]]>
