T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/generate_outfit.py:85
- Finding
- Unrestricted Retrieval and Processing of Server-Controlled URLs<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_outfit.py`, lines 85–90 and 103–109 **Vulnerability Type**: Unrestricted URL retrieval, client-side SSRF, and unsafe processing of remote files **Risk Level**: Medium ### Vulnerable Code ```python def download(url, dest): try: request.urlretrieve(url, str(dest)) return True except Exception: return False def magick(*args): subprocess.run(["magick"] + list(args), check=True, capture_output=True) # ===== Compose each outfit ===== outfit_desc = [] for i, outfit in enumerate(outfits): ar = outfit.get("canvas_content", {}).get("aspect_ratio", 0.731) cw = int(CANVAS_H * ar) out_path = OUTDIR / f"outfit_{i+1}.png" magick("-size", f"{cw}x{CANVAS_H}", "xc:#FFFFFF", str(out_path)) products = sorted(outfit.get("product_list", []), key=lambda p: p.get("z_index", 0)) names = [] for p in products: names.append(p.get("class_name", "单品")) img_url = p.get("cutout_image", "") if not img_url: continue item_path = OUTDIR / "item_tmp.png" if not download(img_url, item_path): continue ``` ### Technical Analysis The `cutout_image` value originates from the remote outfit API response and is passed directly to `urllib.request.urlretrieve()` without validation. The implementation does not restrict: - The permitted URL scheme. - The source hostname. - Redirect destinations. - Loopback, private, link-local, or reserved IP addresses. - Local-resource schemes such as `file:`. - Response content type. - Download size or image dimensions. Consequently, a compromised or malicious API endpoint can cause the client to make requests to resources that are not part of the intended image service. This creates a client-side SSRF primitive and may permit access to local files supported by the URL handler. The downloaded data is subsequently supplied to ImageMagick. An attacker can therefore also ...[truncated 1933 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Permit only `https` URLs from an explicit allowlist of trusted image-hosting domains. 2. Reject URLs containing credentials, unexpected ports, or unsupported schemes. 3. Resolve the destination hostname and reject loopback, private, link-local, multicast, unspecified, and reserved addresses for both IPv4 and IPv6. 4. Disable automatic redirects or validate every redirect target using the same scheme, hostname, and resolved-address rules. 5. Stream downloads into an exclusively created temporary file while enforcing a strict byte limit. 6. Require an expected image MIME type and verify the downloaded file using an image parser before invoking ImageMagick. 7. Enforce maximum image dimensions, frame counts, decode time, memory consumption, and disk usage. 8. Run ImageMagick with a restrictive `policy.xml`, disable unnecessary coders and delegates, and keep the installed version patched. 9. Consider processing untrusted images in an isolated sandbox without access to sensitive files, internal networks, or unnecessary system privileges. ]]>
