T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/fetch_clean_headlines.py:4
- Finding
- Unrestricted URL Fetching Enables Server-Side Request Forgery## Vulnerability Details **File Location**: `scripts/fetch_clean_headlines.py`, lines 4–14 **Vulnerability Type**: Server-Side Request Forgery through an unrestricted outbound request **Risk Level**: Medium ```python def fetch_clean_headlines(source_name: str, url: str, limit: int = 3, keywords: list = None, negative_keywords: list = None) -> str: try: headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Accept': 'application/rss+xml, application/xml, text/xml, */*' } with httpx.Client(timeout=15.0, headers=headers, follow_redirects=True) as client: response = client.get(url) ``` ### Technical Analysis The `fetch_clean_headlines` function accepts a URL and passes it directly to `httpx.Client.get()` without validating its scheme, hostname, resolved IP address, or destination port. The HTTP client is also configured with `follow_redirects=True`, allowing an initially external URL to redirect the request to an internal destination. If an untrusted user or Agent-controlled workflow can provide the `url` argument, the function can be used as a server-side request forgery primitive. Potential destinations include loopback interfaces, private network ranges, link-local services, and cloud instance metadata endpoints. Because the response is subsequently parsed as a feed, XML- or RSS-compatible internal responses may be exposed through generated headline output. The current executable entry point uses hardcoded public feed URLs. Exploitation therefore requires another caller to invoke this reusable function with attacker-controlled input. This usage is plausible because `SKILL.md` describes feed URL input, although the documented interactive prompt is not implemented in the reviewed script. ### Attack Path 1. An attacker supplies a URL to a workflow that passes it ...[truncated 1106 chars]
- Remediation
- ## Remediation Suggestions - Accept only `https` URLs and reject URLs containing credentials, unexpected ports, fragments, or ambiguous hostname syntax. - Maintain an explicit allowlist of approved feed hostnames rather than permitting arbitrary destinations. - Resolve the hostname before connecting and reject loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 addresses. - Disable automatic redirects unless they are required. If redirects are enabled, validate every redirect target using the same scheme, hostname, and resolved-address restrictions. - Account for DNS rebinding by ensuring that the address validated is the address used for the connection, or enforce outbound restrictions at the network layer. - Apply egress firewall rules that prevent the process from reaching internal networks and cloud metadata addresses. - Add tests covering direct internal URLs, IPv6 loopback addresses, alternative IP representations, DNS rebinding scenarios, and public URLs that redirect to private destinations. - If only the hardcoded feeds are intended, remove the public URL parameter and map approved source identifiers to fixed URLs internally.
