T09 · Insecure Skill Coding Practices
- Location
scripts/fetch_rss.py:126- Finding
Server-Side Request Forgery Through Unvalidated RSS Destinations and Redirects
- Content
View full analysis
Vulnerability Details
File Location:
scripts/fetch_rss.py:126-150
Vulnerability Type: Server-Side Request Forgery (SSRF)
Risk Level: MediumVulnerable Code
python def fetch(url, limit): parsed_url = urllib.parse.urlparse(url) if parsed_url.scheme not in {"http", "https"}: raise ValueError("only HTTP(S) feed URLs are allowed") request = urllib.request.Request( url, headers={ "User-Agent": "YoooClaw-RSS/1.0 (+https://clawhub.ai/)", "Accept": "application/rss+xml, application/atom+xml, text/xml, application/xml", }, ) with urllib.request.urlopen(request, timeout=15) as response: final_url = response.geturl() content = response.read(MAX_RESPONSE_BYTES + 1) if len(content) > MAX_RESPONSE_BYTES: raise ValueError("feed response exceeds 5 MiB") root = ET.fromstring(content) if local_name(root.tag) == "feed": feed_title, items = parse_atom(root, final_url, limit) else: feed_title, items = parse_rss(root, final_url, limit) return { "ok": True, "feed_title": feed_title, "url": final_url,Technical Analysis
The URL validation only permits
httpandhttpsschemes. It does not reject loopback, private, link-local, reserved, unspecified, multicast, or cloud metadata addresses.Furthermore,
urllib.request.urlopen()follows HTTP redirects automatically. The resultingfinal_urlis retrieved but is not subjected to any destination validation. Therefore, an initially trusted public RSS endpoint can redirect the request to a network location that should not be reachable through the Skill.The documented workflow limits normal execution to 17 fixed public feeds, which reduces direct attacker control over the initial URL. However, it does not mitigate a compromised or misconfigured feed, an unsafe redirect, or applicable DNS manipulation. The client can retrieve up to 5 MiB from t ...[truncated 1586 chars]
- Remediation
View remediation
Remediation Suggestions
-
Require HTTPS for configured feeds
- Reject plain HTTP initial URLs.
- Reject redirects that downgrade from HTTPS to HTTP.
-
Enforce an exact destination allowlist
- Maintain an explicit list of approved RSS hostnames.
- Validate both the initial URL and every redirect target against that list.
- Compare canonicalized hostnames rather than using suffix or substring matching.
-
Validate resolved IP addresses
- Resolve the destination before connecting.
- Reject loopback, private, link-local, multicast, reserved, unspecified, and documentation-only address ranges for both IPv4 and IPv6.
- Validate every address returned by DNS resolution.
-
Control redirects
- Disable automatic redirects and process them explicitly, or install a redirect handler that validates every
Locationtarget. - Set a small maximum redirect count.
- Revalidate the final URL and its resolved address before accepting the response.
- Disable automatic redirects and process them explicitly, or install a redirect handler that validates every
-
Mitigate DNS rebinding
- Ensure the address validated is the address used for the connection.
- Revalidate destination addresses after redirects.
- Prefer network-layer egress controls that deny access to internal and link-local ranges.
-
Apply defense in depth
- Run the RSS process with restricted network egress.
- Preserve the existing timeout and response-size limits.
- Log rejected destinations without exposing credentials or sensitive response content.
- Add tests covering redirects to
127.0.0.1,::1, RFC 1918 networks, link-local ranges, and common cloud metadata addresses.
-
