T09 · Insecure Skill Coding Practices
- Location
scripts/flk_npc_client.py:383- Finding
Unvalidated Server-Supplied Download URL Permits Requests to Arbitrary Destinations
- Content
View full analysis
str: try: data = self._request( "GET", "/law-search/download/pc", params={"format": fmt, "bbbs": bbbs, "fileId": ""}, ) inner = data.get("data", data) if isinstance(inner, dict): return inner.get("url", "") return str(inner) if inner else "" except Exception: return "" def download_file(self, bbbs: str, save_path: str, fmt: str = "docx") -> str: dl_url = self.get_download_url(bbbs, fmt) if not dl_url: raise RuntimeError(f"Failed to obtain download URL for bbbs={bbbs}") resp = requests.get(dl_url, timeout=60) resp.raise_for_status() with open(save_path, "wb") as f: f.write(resp.content) return save_path ``` ### Technical Analysis The download URL returned by the remote API is passed directly to `requests.get()` without validating its scheme, hostname, port, resolved IP address, or redirect destination. Because `requests` follows redirects by default, validating only the initial API endpoint does not constrain the second request. If the API response is compromised, spoofed through an upstream failure, or made to return an unsafe redirect, the client could request an arbitrary Internet or internal-network resource. The response is accessed through `resp.content`, which buffers the entire body in memory, and is then written without a maximum size, content-type check, or file-signature validation. When the requested format is DOCX, the resulting file may subsequently be parsed by `python-docx`. Consequently, untrusted remote content reaches a document parser without prior structural validation. This behavior does not estab ...[truncated 1702 chars]- Remediation
View remediation
