T09 · Insecure Skill Coding Practices
Warning
- Location
- 3daistudio.py:96
- Finding
- Unvalidated Server-Provided Asset URL Enables Arbitrary Resource Retrieval<![CDATA[ ## Vulnerability Details **File Location**: `3daistudio.py`, lines 96–106 **Vulnerability Type**: Server-Side Request Forgery (SSRF) and unsafe remote file retrieval **Risk Level**: Medium ### Vulnerable Code ```python entry = preferred or results[0] asset_url = entry.get("asset") or entry.get("asset_url") if not asset_url: print("No asset URL in results.") print(json.dumps(entry, indent=2)) return print(f" Downloading from: {asset_url}") req = urllib.request.Request(asset_url) with urllib.request.urlopen(req, timeout=60) as r: with open(output_path, "wb") as f: f.write(r.read()) ``` ### Technical Analysis The application obtains `asset_url` from a remote API response and passes it directly to `urllib.request.urlopen()` without validating: - The URL scheme - The destination hostname - The resolved IP address - Redirect destinations - The response content type - The response size The 3D AI Studio API or an intermediary controlling its response can therefore instruct the client to request an arbitrary URL from the agent's network context. Depending on the URL handlers and network environment available to Python, destinations could include loopback services, private-network services, link-local cloud metadata endpoints, or local resources. This network access is not required at arbitrary destinations. The declared functionality only requires downloading generated assets from trusted 3D AI Studio infrastructure or an explicitly approved CDN. Consequently, unrestricted handling of API-supplied URLs exceeds the minimum network privileges needed by the Skill. The downloaded response is written directly to the user-selected output path without checking that it is a valid 3D model. This also allows the remote service to substitute arbitrary content for the expected model. The application does not automatically execute the downloaded file, which limits the immediate code-execution impact. The separately flagged Base64 behavior ...[truncated 2141 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Restrict URL schemes** - Accept only `https`. - Explicitly reject `file`, `ftp`, `data`, and other schemes. 2. **Allowlist trusted asset hosts** - Permit downloads only from documented 3D AI Studio and approved CDN hostnames. - Compare normalized hostnames exactly; do not use insecure suffix matching. 3. **Validate resolved addresses** - Resolve the hostname before connecting. - Reject loopback, private, link-local, multicast, reserved, and unspecified IPv4 and IPv6 ranges. - Protect against DNS rebinding by ensuring the validated address is the address used for the connection. 4. **Validate redirects** - Disable automatic redirects or validate every redirect destination using the same scheme, hostname, and IP checks. - Apply a small redirect limit. 5. **Constrain the response** - Enforce a maximum download size while streaming rather than calling unrestricted `r.read()`. - Validate the expected content type where the provider supplies a stable type. - Verify the downloaded format or archive structure before treating it as a model. - Remove partial output if validation or download fails. 6. **Use safe output handling** - Write to a temporary file in the destination directory. - Validate the completed file and then atomically rename it to the requested output path. - Avoid overwriting existing files unless the user explicitly approves it. A hardened design should obtain either a trusted-host HTTPS URL or an asset identifier that is downloaded through a fixed, authenticated API endpoint rather than accepting an unrestricted URL from the response. ]]>
