T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/run_seedance.py:188
- Finding
- Unrestricted Local File Upload Can Expose Sensitive Host Data## Vulnerability Details **File Location**: `scripts/run_seedance.py:188-201`, with the resulting network transmission at `scripts/run_seedance.py:219-225` and `scripts/run_seedance.py:255-262` **Vulnerability Type**: Arbitrary local file disclosure through unrestricted multipart upload **Risk Level**: High ### Vulnerable Code ```python def open_files_for_upload(paths: List[str]) -> List[Tuple[str, Tuple[str, Any, str]]]: """Open local files and return list of (form_key, (filename, fileobj, content_type)) for multipart upload.""" result = [] for path in paths: path = path.strip() if not path: continue if not os.path.isfile(path): raise FileNotFoundError(f"File not found: {path}") f = open(path, "rb") name = os.path.basename(path) mime, _ = mimetypes.guess_type(path) mime = mime or "application/octet-stream" result.append(("files", (name, f, mime))) return result ``` The files selected by this function are passed directly to the remote service: ```python upload_paths = filter_files_by_url_overrides( file_paths=args.files or [], image_urls=image_urls or [], video_urls=video_urls or [], audio_urls=audio_urls or [], ) file_tuples = open_files_for_upload(upload_paths) if upload_paths else [] ``` ```python resp = requests.post( VID_URL, headers={ "Authorization": f"Bearer {api_key}", }, data=data, files=file_tuples, timeout=120, ) ``` ### Technical Analysis The `--files` argument accepts arbitrary filesystem paths. The implementation checks only whether each path refers to a regular file. It does not: - Restrict files to a dedicated upload or workspace directory. - Resolve and validate canonical paths against an approved root. - Reject symbolic links that resolve outside an approved directory. - Restrict uploads to supported image, video, or audio formats. - Validate file contents against their claime ...[truncated 1970 chars]
- Remediation
- ## Remediation Suggestions 1. Create a dedicated media-upload directory, such as `workspace/assets`, and permit uploads only from that directory. 2. Resolve every supplied path with `Path.resolve(strict=True)` and verify that the canonical path remains under the approved root. 3. Reject symbolic links or open files using platform-supported no-follow protections to reduce symlink and time-of-check/time-of-use risks. 4. Allowlist supported media types and extensions. Reject `other` files rather than uploading them as `application/octet-stream`. 5. Inspect file signatures with a trusted media parser instead of relying solely on filename-based `mimetypes.guess_type()`. 6. Enforce per-file and aggregate upload-size limits before opening or transmitting data. 7. Require explicit user confirmation listing the canonical path, detected media type, size, and destination before upload. 8. Run the Skill under an operating-system identity with access only to the intended workspace and no unnecessary credential directories. 9. Log upload metadata without recording file contents or authorization tokens.
