T09 · Insecure Skill Coding Practices
- Location
scripts/fetch_coin_news.py:153- Finding
Unrestricted Configurable URL Fetching Enables SSRF and Local Resource Access
- Content
View full analysis
bytes: request = urllib.request.Request(url, headers={"User-Agent": user_agent}) with urllib.request.urlopen(request, timeout=timeout) as response: return response.read() ``` The unvalidated URL is obtained from the source configuration and passed directly to the network sink: ```python for source in sources["sources"]: if not source.get("enabled", True): continue try: feed_bytes = fetch_url( source["url"], sources["defaults"]["user_agent"], int(sources["defaults"]["request_timeout_seconds"]), ) ``` ### Technical Analysis Every enabled `source["url"]` from `references/sources.yaml` is passed directly to `urllib.request.urlopen`. The code does not enforce HTTPS, validate the hostname, restrict allowed ports, reject non-network URL schemes, resolve and inspect destination IP addresses, or validate redirect destinations. The committed configuration contains ordinary public HTTPS news feeds. Nevertheless, anyone capable of supplying or modifying the source configuration can cause the process to access destinations unrelated to cryptocurrency news, including loopback services, private network addresses, link-local addresses, or local resources supported by the URL handler. A timeout limits how long the request may run but does not constrain where it can connect. Redirects also need validation because an initially acceptable public URL could redirect to a prohibited destination. ### Attack Path 1. An attacker gains the ability to add or modify an enabled entry in `references/sources.yaml`, or influences an equivalent configuration supplied to the Skill. ...[truncated 1200 chars]- Remediation
View remediation
