T09 · Insecure Skill Coding Practices
- Location
monitor.py:19- Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery in the Primary Entry Point
- Content
View full analysis
Vulnerability Details
File Location:
monitor.py:19-31andmonitor.py:137-144
Vulnerability Type: Server-Side Request Forgery (SSRF)
Risk Level: HighVulnerable code:
python def fetch_url_content(url): """Fetch webpage content.""" headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' } try: # SSL verification is enabled response = requests.get(url, headers=headers, timeout=30, verify=True) response.raise_for_status() return response.text except requests.exceptions.SSLError as e: return f"ERROR: SSL verification failed - {str(e)}" except Exception as e: return f"ERROR: {str(e)}" def main(): """Main function.""" if len(sys.argv) < 2: print("Usage: monitor.py <url> [rule]") sys.exit(1) url = sys.argv[1] rule = sys.argv[2] if len(sys.argv) > 2 else "content" content = fetch_url_content(url)Technical Analysis
The primary entry point accepts a caller-controlled URL and passes it directly to
requests.get. It does not validate the URL scheme, destination hostname, resolved IP address, port, or redirect chain.Consequently, a caller able to invoke the Skill can cause the trusted OpenClaw host to send HTTP requests to destinations that may not be accessible from the caller's own network position. Potential targets include loopback services, RFC1918 private networks, link-local services, and cloud metadata endpoints. The
verify=Truesetting validates TLS certificates for HTTPS connections but does not prevent SSRF.Redirects are followed by
requestsby default. Therefore, validating only the initial URL in a future partial fix would remain insufficient: an apparently public endpoint could redirect the request to an internal address.The returned page is primarily hashed or parsed rather than printed ...[truncated 1813 chars]
- Remediation
View remediation
Remediation Suggestions
- Parse URLs with
urllib.parse.urlsplitand permit only explicitly supportedhttpandhttpsschemes. - Reject URLs containing embedded credentials, malformed hostnames, unsupported ports, or ambiguous address representations.
- Resolve the hostname before connecting and reject every address classified as loopback, private, link-local, reserved, multicast, unspecified, or otherwise non-global.
- Disable automatic redirects with
allow_redirects=False, or validate and resolve every redirect destination before following it. - Prefer a per-user allowlist of domains that the user has explicitly approved for monitoring.
- Apply outbound firewall or proxy controls that block access to loopback, private networks, and cloud metadata addresses.
- Protect against DNS rebinding by ensuring that the validated address is the address used for the connection, or route requests through a hardened egress proxy.
- Add response-size limits and streaming limits to reduce resource-exhaustion risk.
- Record rejected destinations and notification failures without exposing sensitive internal connection details.
- Add automated tests covering IPv4, IPv6, encoded IP addresses, redirects, DNS rebinding scenarios, localhost aliases, and metadata endpoints.
- Parse URLs with
