T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/live_theft_handler.py:297
- Finding
- Unvalidated Server-Provided Log URL Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/live_theft_handler.py:297-327` **Vulnerability Type**: Server-side request forgery through unrestricted URL retrieval **Risk Level**: Medium ### Complete Code Snippet ```python for group in resp.get("DomainLogDetails", {}).get("DomainLogDetail", []): for detail in group.get("LogInfos", {}).get("LogInfoDetail", []): log_url = detail.get("LogPath", "") if log_url: # The LogPath returned by the API sometimes lacks a scheme if not log_url.startswith(("http://", "https://")): log_url = "https://" + log_url paths.append(log_url) return paths def download_log_text(url, timeout=60): """Download a log file (supports .gz and plain text) and return its text.""" try: req = urllib.request.Request(url) with urllib.request.urlopen(req, timeout=timeout) as resp: data = resp.read() content_encoding = resp.headers.get("Content-Encoding", "").lower() except urllib.error.HTTPError as e: body = e.read().decode("utf-8", errors="replace") raise RuntimeError(f"Failed to download log, HTTP {e.code}: {body}") from e # Detect gzip via Content-Encoding, magic bytes, or file extension is_gzip = ( content_encoding == "gzip" or data.startswith(b"\x1f\x8b") or url.split("?")[0].endswith(".gz") ) if is_gzip: with gzip.GzipFile(fileobj=io.BytesIO(data)) as gz: return gz.read().decode("utf-8", errors="replace") return data.decode("utf-8", errors="replace") ``` ### Technical Analysis The complete `LogPath` returned by the Alibaba Cloud API is accepted as a network destination. The implementation checks only whether the string begins with `http://` or `https://`; it does not validate the destination hostname, resolved address, port, or redirect chain. Consequently, a manipulated API response, compromised account-side log recor ...[truncated 1974 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require HTTPS and reject plaintext HTTP log URLs. 2. Allowlist the exact Alibaba Cloud storage and log-delivery host suffixes documented for `DescribeLiveDomainLog`. 3. Parse URLs with `urllib.parse.urlsplit()` and reject: - Embedded credentials - Unexpected ports - Missing hostnames - IP-literal hosts unless explicitly required 4. Resolve the hostname before connecting and reject loopback, private, link-local, multicast, reserved, and unspecified addresses using Python's `ipaddress` module. 5. Disable automatic redirects or implement a redirect handler that repeats all validation for every destination. 6. Protect against DNS rebinding by connecting only to a validated resolved address while preserving the expected TLS hostname, or use a networking library that supports controlled resolution safely. 7. Return a structured error when a URL falls outside the approved Alibaba log-delivery boundary. 8. Avoid including complete signed log URLs in output because their query parameters may provide temporary access to sensitive logs. ]]>
