T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/upload.py:85
- Finding
- Unvalidated API-Provided Upload Endpoint Receives Credentials and File Data<![CDATA[ ## Vulnerability Details **File Location**: `scripts/upload.py:85-94`, `scripts/upload.py:143-166`, `scripts/upload.py:328-339` **Vulnerability Type**: Improper validation of a remotely supplied network endpoint **Risk Level**: Medium ### Code Snippet ```python def get_upload_domain(): """Get upload domain from API.""" resp = requests.get( f"{API_BASE}/upload/v2/file/domain", headers=get_headers(), timeout=30 ) resp.raise_for_status() data = resp.json() if data.get("code") != 0: raise Exception(f"Failed to get upload domain: {data}") return data["data"][0] ``` ```python def upload_slice_v2(upload_server: str, preupload_id: str, slice_no: int, data: bytes, max_retries: int = 3) -> bool: """Upload a single slice using v2 API (multipart/form-data POST).""" import time url = f"{upload_server}/upload/v2/file/slice" slice_md5 = hashlib.md5(data).hexdigest() headers = get_upload_headers() for attempt in range(max_retries): try: files = { "slice": (f"slice_{slice_no}", data, "application/octet-stream") } form_data = { "preuploadID": preupload_id, "sliceNo": slice_no, "sliceMD5": slice_md5 } resp = requests.post( url, headers=headers, data=form_data, files=files, timeout=300 ) ``` ```python upload_domain = get_upload_domain() url = f"{upload_domain}/upload/v2/file/single/create" headers = get_upload_headers() data = { "parentFileID": folder_id, "filename": filename, "etag": etag, "size": file_size, "duplicate": 1 } with open(file_path, "rb") as f: files = {"file": (filename, f)} resp = requests.post(url, headers=headers, data=data, files=files, timeout=300) ``` ### Technical Analysis The upload host returned by `https: ...[truncated 1937 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse API-provided URLs with `urllib.parse.urlparse`. 2. Require the `https` scheme and reject embedded credentials, fragments, unexpected ports, and malformed hostnames. 3. Enforce an allowlist of documented 123pan upload domains or strictly validated domain suffixes. Domain checks must require either an exact match or a dot-delimited subdomain match to prevent suffix-confusion attacks. 4. Apply the same validation to both the single-upload domain and every entry in the chunked-upload `servers` list. 5. Do not send the API bearer token to storage hosts unless the official protocol explicitly requires it. Prefer short-lived, upload-scoped credentials or presigned URLs. 6. Disable cross-origin authorization forwarding during redirects, or reject redirects entirely for upload requests. 7. Add tests covering malicious values such as `http://`, attacker-owned HTTPS hosts, embedded credentials, deceptive suffixes, IP literals, and nonstandard ports. ]]>
