T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/fetch_feeds.py:16
- Finding
- Unrestricted Resource Fetching Enables SSRF and Local Resource Access<![CDATA[ ## Vulnerability Details **File Location**: `scripts/fetch_feeds.py:16-18` **Vulnerability Type**: Unrestricted URL and resource fetching **Risk Level**: Medium ### Vulnerable Code ```python def fetch_feed(url, max_age_days=None, keyword_filter=None): """Fetch and filter feed entries.""" feed = feedparser.parse(url) ``` The URL originates directly from a command-line argument at `scripts/fetch_feeds.py:42-54`: ```python if __name__ == '__main__': url = sys.argv[1] if len(sys.argv) > 1 else '' max_age = int(sys.argv[2]) if len(sys.argv) > 2 else None keyword = sys.argv[3] if len(sys.argv) > 3 else None if not url: print(json.dumps({'error': 'URL required'})) sys.exit(1) result = fetch_feed(url, max_age, keyword) print(json.dumps(result, indent=2)) ``` ### Technical Analysis The script passes a caller-controlled resource identifier directly to `feedparser.parse()` without validating the scheme, destination host, resolved IP address, redirects, or whether the input is a local path. Depending on the schemes and handlers supported by the installed parser and Python runtime, this can allow: - Requests to loopback services such as `127.0.0.1`. - Requests to private or link-local network addresses. - Access to cloud instance metadata endpoints. - Parsing of local files or paths accessible to the process. - Redirect-based bypasses in which an initially acceptable URL redirects to a restricted destination. Any resulting document that can be interpreted as feed data may be included in the JSON output. The documented scheduling and webhook workflows can subsequently transmit that output to another service. ### Attack Path 1. An attacker, untrusted user, or compromised Agent workflow supplies a malicious feed resource as the first command-line argument. 2. The script forwards the value to `feedparser.parse()` without validation. 3. The parser accesses an internal service, link-local endpoint, or local r ...[truncated 999 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse the input with `urllib.parse.urlsplit` and allow only explicitly required schemes, preferably `https`. 2. Reject local paths, `file:` URLs, embedded credentials, malformed hostnames, and nonstandard schemes. 3. Resolve the destination hostname before connecting and reject: - Loopback addresses. - Private network addresses. - Link-local addresses. - Multicast, reserved, and unspecified addresses. 4. Revalidate the destination after every redirect to prevent redirect-based SSRF bypasses. 5. Use a controlled HTTP client with explicit connection and read timeouts. 6. Set maximum redirect, response-size, and entry-count limits. 7. Consider an allowlist of approved feed domains for scheduled jobs. 8. Run the process in a sandbox with restricted filesystem and network access. 9. Avoid automatically forwarding fetched data to external services unless the destination and content have been validated. ]]>
