T09 · Insecure Skill Coding Practices
- Location
scripts/chinese_copy_image.py:226- Finding
API-Provided Upload and Download URLs Are Not Restricted to Trusted Hosts
- Content
View full analysis
Vulnerability Details
File Location:
scripts/chinese_copy_image.py:226-246,scripts/chinese_copy_image.py:323-355
Vulnerability Type: Insufficient validation of remote transfer destinations
Risk Level: MediumVulnerable Code
python def upload(api, filename): path, content_type = source_file(filename) ticket = api.upload_ticket(path, content_type) media_id = ticket["mediaId"] transfer = ticket["upload"] url = transfer["url"] if urlparse(url).scheme != "https": raise SystemExit("素材上传地址必须使用 HTTPS") try: with path.open("rb") as handle: response = requests.request( transfer.get("method", "PUT"), url, headers=transfer.get("headers", {}), data=handle, timeout=300, ) except requests.RequestException as exc: raise SystemExit("素材上传失败:" + str(exc)) if not response.ok: raise SystemExit( "素材上传失败 {}:{}".format(response.status_code, response.text) ) api.complete_upload(media_id) print("[source]", path.name, "->", media_id) return media_idpython def safe_download(url, destination): if urlparse(url).scheme != "https": raise SystemExit("结果下载地址必须使用 HTTPS") destination.parent.mkdir(parents=True, exist_ok=True) try: with requests.get(url, stream=True, timeout=300) as response: response.raise_for_status() with destination.open("wb") as handle: for chunk in response.iter_content(8192): if chunk: handle.write(chunk) except requests.RequestException as exc: raise SystemExit("结果下载失败:" + str(exc)) print("[saved]", destination) def wait_and_download(api, task_id, output_dir, project): deadline = time.time() + 1200 task = None while time.time() < deadline: ...[truncated 3411 chars]- Remediation
View remediation
Remediation Suggestions
- Maintain an explicit allowlist of approved upload and download hostnames and ports.
- Resolve destination hostnames and reject loopback, private, link-local, multicast, reserved, and cloud metadata addresses.
- Disable automatic redirects with
allow_redirects=False, or validate the scheme, hostname, port, and resolved address at every redirect. - Permit only the documented upload methods, such as
PUTorPOST, rather than accepting an arbitrary API-provided method. - Filter API-provided headers against a narrow allowlist and reject sensitive or unexpected headers.
- Validate downloaded
Content-Type, enforce a maximum response size, and verify the image's magic bytes before saving it. - Write downloads to a temporary file, validate them, and then atomically rename them to the final destination.
- Consider binding transfer tickets cryptographically to the expected media identifier, destination, size, and expiration where supported by the service.
