T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/happyhorse-magic.py:32
- Finding
- Unrestricted Local File Encoding and Upload to an External API<![CDATA[ ## Vulnerability Details **File Location**: `scripts/happyhorse-magic.py`, lines 32–46; network transmission paths at lines 184, 249–250, and 349–353 **Vulnerability Type**: Arbitrary local file disclosure through insufficient input validation **Risk Level**: Medium ### Vulnerable Code ```python def encode_local_file(path): """If path is a local file, return a data URI (data:{mime};base64,...). Otherwise return the original string (assumed to be a URL).""" if path.startswith(("http://", "https://", "oss://", "data:")): return path abs_path = os.path.expanduser(path) if not os.path.isfile(abs_path): print(f"Error: file not found: {abs_path}", file=sys.stderr) sys.exit(1) mime, _ = mimetypes.guess_type(abs_path) if mime is None: mime = "application/octet-stream" with open(abs_path, "rb") as f: b64 = base64.b64encode(f.read()).decode("utf-8") print(f" [base64] Encoded local file: {abs_path} ({mime}, {len(b64)} chars)") return f"data:{mime};base64,{b64}" ``` The resulting data URI is placed into outbound request payloads through the following paths: ```python # image2video_gen media = [{"type": "first_frame", "url": encode_local_file(args.first_frame)}] ``` ```python # reference2video_gen for ref_image in args.reference_images: media.append({"type": "reference_image", "url": encode_local_file(ref_image)}) ``` ```python # video_edit media = [{"type": "video", "url": encode_local_file(args.video)}] if args.reference_images: for img in args.reference_images: media.append({"type": "reference_image", "url": encode_local_file(img)}) ``` These payloads are subsequently transmitted using `requests.post()` to the fixed external endpoint: ```python BASE_URL = "https://dashscope.aliyuncs.com" ``` ### Technical Analysis The documented interface describes the image and video arguments as media URLs. The implementation additionally treats any argument that does n ...[truncated 3070 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Require explicit local-file syntax** - Treat media arguments as URLs by default. - If local upload is necessary, expose a clearly named option such as `--local-first-frame`. - Require explicit user confirmation before transmitting a local file to an external service. 2. **Restrict permissible filesystem locations** - Resolve paths with `os.path.realpath()` or `pathlib.Path.resolve()`. - Permit files only under a configured workspace or approved media directory. - Reject traversal and symlink resolutions that escape the approved directory. 3. **Enforce media allowlists** - Allow only the formats documented for each command. - For images, restrict input to JPEG, PNG, and WEBP. - For videos, restrict input to supported MP4 or MOV content. - Reject `application/octet-stream` rather than using it as a fallback. 4. **Validate actual file content** - Do not rely solely on filename extensions or `mimetypes`. - Inspect magic bytes and parse the file using a trusted media library. - Verify that the detected content type matches the expected argument type. 5. **Enforce size limits before reading** - Use `os.path.getsize()` before opening the file. - Enforce the documented image and video limits. - Avoid unbounded `f.read()`; use bounded or streaming processing where supported. 6. **Reduce accidental secret disclosure** - Reject known sensitive filenames and directories as a defense-in-depth measure, including `.env`, `.ssh`, credential stores, and common cloud configuration paths. - Avoid printing full local paths where logs may be retained. - Clearly document that accepted local files are transmitted to Alibaba DashScope. 7. **Add security-focused tests** - Verify rejection of non-media files, oversized files, symlinks outside the workspace, path traversal attempts, spoofed extensions, and sensitive configuration files. ]]>
