T09 · Insecure Skill Coding Practices
- Location
lib/scraper.py:99- Finding
Unrestricted URL Fetching Enables SSRF and Local Resource Access
- Content
View full analysis
Optional[str]: """HTTP GET with urllib, proper headers, timeout, retry.""" for attempt in range(MAX_RETRIES): try: req = Request(url, headers={'User-Agent': USER_AGENT}) with urlopen(req, timeout=REQUEST_TIMEOUT) as response: html = response.read().decode('utf-8', errors='ignore') return html except (URLError, HTTPError, TimeoutError) as e: if attempt < MAX_RETRIES - 1: time.sleep(2 ** attempt) # Exponential backoff else: return None ``` ### Technical Analysis The CLI accepts an arbitrary URL and stores it as a monitoring target. The stored value is subsequently passed directly to `urllib.request.Request` and `urlopen` without validating: - The URL scheme - The destination hostname or resolved IP address - Whether the destination is loopback, link-local, private, multicast, or reserved - Redirect destinations - Whether the URL contains embedded credentials - Whether the selected URL handler accesses a local resource, such as through a `file://` URL Although `_fetch_page` is described as performing an HTTP GET, `urlopen` supports URL schemes beyond HTTP and HTTPS. Consequently, an attacker who can influence commands supplied to the Agent may cause the process to read local files or connect to services that are reachable from the host but not from the attacker. The fetched response is then processed as webpage content. Extracted content can be written to the SQLite database through `save_price`. The related `t ...[truncated 1706 chars]- Remediation
View remediation
