T09 · Insecure Skill Coding Practices
- Location
scripts/openclaw_quote_autoreply.py:46- Finding
SSRF Protection Can Be Bypassed Through Unvalidated Redirects and DNS Rebinding
- Content
View full analysis
str: """Sanitize API URL to prevent SSRF attacks.""" parsed = urllib.parse.urlparse(url) if parsed.scheme.lower() not in ("http", "https"): raise ValueError(f"API URL must use HTTP or HTTPS scheme: {url}") host = (parsed.hostname or "").lower().rstrip(".") if not host: raise ValueError("API URL must have a valid hostname") # First check: hostname string validation if _is_disallowed_host(host): raise ValueError(f"API URL points to disallowed host: {host}") # Second check: DNS rebinding protection - resolve and validate IP _resolve_and_validate_host(host) # Third check: path traversal prevention path = urllib.parse.unquote(parsed.path or "/") if ".." in path or "//" in path.replace("//", "/"): raise ValueError(f"API URL contains suspicious path traversal: {path}") # Check against allowlist if configured allow_hosts = os.getenv("QUOTLY_API_ALLOW_HOSTS", "") if allow_hosts: allowed = {h.strip().lower().rstrip(".") for h in allow_hosts.split(",") if h.strip()} if host not in allowed: raise ValueError(f"API URL host not in allowlist: {host}") return parsed._replace(fragment="", username=None, password=None).geturl() ``` ```python def _request_quote_api_bytes( api_url: str, payload: Dict[str, Any], timeout_seconds: float ) -> bytes: # Enforce max payload size (1MB) payload_bytes = json.dumps(payload).encode("utf-8") max_payload_size = 1024 * 1024 if len(payload_bytes) > max_payload_size: raise ValueError(f"Payload exceeds maximum size of {max_payload_size} bytes") request = urllib.request.Request( ...[truncated 4165 chars]- Remediation
View remediation
