T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/monitor.py:24
- Finding
- Unrestricted URL Fetching Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/monitor.py:24-37` **Vulnerability Type**: Server-Side Request Forgery (SSRF) **Risk Level**: High ### Complete Code Snippet ```python def fetch_page(url, timeout=15): """Fetch a URL and return (status_code, text, response_time_ms).""" start = time.time() try: resp = requests.get(url, headers=HEADERS, timeout=timeout, allow_redirects=True) elapsed = int((time.time() - start) * 1000) # Extract text content (strip HTML roughly) text = re.sub(r"<script[^>]*>.*?</script>", "", resp.text, flags=re.DOTALL) text = re.sub(r"<style[^>]*>.*?</style>", "", text, flags=re.DOTALL) text = re.sub(r"<[^>]+>", " ", text) text = re.sub(r"\s+", " ", text).strip() return resp.status_code, text, elapsed except requests.exceptions.Timeout: elapsed = int((time.time() - start) * 1000) return 0, "", elapsed ``` All command modes ultimately pass caller-controlled URLs to this function. The relevant command arguments are defined at `scripts/monitor.py:153-166`: ```python p_check.add_argument("url") p_watch = sub.add_parser("watch", help="Detect changes vs last snapshot") p_watch.add_argument("url") p_watch.add_argument("--state-dir", default="/tmp/monitor-state") p_match = sub.add_parser("match", help="Check for content pattern") p_match.add_argument("url") p_match.add_argument("--pattern", required=True) p_batch = sub.add_parser("batch", help="Batch check from file") p_batch.add_argument("file") p_batch.add_argument("--state-dir", default="/tmp/monitor-state") ``` ### Technical Analysis The monitor makes outbound requests to user-controlled URLs without validating the URL scheme, hostname, port, or resolved IP address. It also enables automatic redirects through `allow_redirects=True` without validating each redirect destination. An attacker who can influence a direct command argument or an entry in a batch file can caus ...[truncated 1908 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Accept only explicitly supported schemes, preferably `https` and, where necessary, `http`. 2. Reject URLs containing embedded credentials or malformed authority components. 3. Resolve the destination hostname before connecting and reject every resolved address belonging to loopback, private, link-local, multicast, unspecified, reserved, or otherwise non-public ranges. 4. Disable automatic redirects or process redirects manually and repeat the complete scheme, hostname, and resolved-IP validation for every destination. 5. Explicitly block known cloud metadata endpoints and link-local metadata ranges. 6. Consider enforcing a domain allowlist when the intended monitoring targets are known. 7. Account for DNS rebinding by ensuring that the validated IP is the address actually used for the connection. 8. Apply outbound firewall or proxy controls so the monitoring process cannot access sensitive internal networks. 9. Add tests covering IPv4, IPv6, alternate address representations, redirects, DNS rebinding scenarios, and public hostnames resolving to private addresses. ]]>
