T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:43
- Finding
- Shell Command Injection and Arbitrary File Write Through Unsanitized Output Filename<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 43–52 **Vulnerability Type**: Unsanitized shell command construction **Risk Level**: High ### Vulnerable Code ```bash curl -L "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=<internal_video_id>&ratio=720p&line=0" \ -H "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15" \ -H "Referer: https://www.douyin.com/" \ -o ~/Downloads/<output_filename>.mp4 ``` ```markdown - Save to `~/Downloads/` using the video title as filename ``` ### Technical Analysis The skill instructs the agent to construct a shell command by replacing `<output_filename>` with the video title. The output path is not quoted, and the instructions do not require filename validation, path normalization, or shell escaping. Video titles and related share text are externally controlled data. If such data is inserted literally into this command, shell metacharacters such as `;`, `$(...)`, backticks, pipes, or redirection operators can be interpreted by the shell. Spaces or a leading hyphen can also alter command arguments. Path separators and `..` components could cause the output to be written outside `~/Downloads`. The same workflow also interpolates the extracted internal video identifier into the request URL without defining an allowlist. Although the URL is enclosed in double quotes, shell substitutions remain active inside double-quoted strings if unsafe text is inserted directly. Both identifiers and filenames should therefore be validated rather than merely quoted. ### Attack Path 1. An attacker creates or supplies a Douyin video whose title or accompanying share text contains shell metacharacters or path traversal components. 2. The victim asks the agent to download the supplied video. 3. Following the skill instructions, the agent uses the externally derived title as `<output_filename>`. 4. The agent constructs and executes the documented `curl` command without sanit ...[truncated 975 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not construct the download command through shell string interpolation. Use a process execution API that accepts an argument array and does not invoke a shell. 2. Validate the public video ID as digits only, with an expected length bound. 3. Validate the internal video ID against a strict allowlist such as `^[A-Za-z0-9_-]{1,128}$`; reject all nonmatching values. 4. Derive filenames through a dedicated sanitizer: - Remove path separators, control characters, and shell metacharacters. - Reject `.` and `..` path components. - Remove leading hyphens. - Apply a conservative character allowlist. - Enforce a reasonable maximum length. 5. Resolve and normalize the destination path, then verify that it remains beneath the intended `~/Downloads` directory. 6. Prefer a fixed filename based on the validated video ID, such as `douyin-<validated_id>.mp4`, rather than using remote metadata. 7. If shell execution is unavoidable, quote the complete destination path after sanitization and pass `--` where supported to terminate option parsing. Shell quoting alone must not replace input validation. 8. Create downloads with safe overwrite behavior, such as refusing to replace existing files or generating a unique destination filename. ]]>
