T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:116
- Finding
- Shell Command Injection Through Unsafe Request-Body Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 116–126 and 199–211 **Vulnerability Type**: Shell command injection caused by unsafe interpolation of user-controlled values **Risk Level**: High ### Vulnerable Code Lines 116–126: ```bash curl -s -X POST https://api.pixwith.ai/api/task/create \ -H "Content-Type: application/json" \ -H "Api-Key: $PIXWITH_API_KEY" \ -d '{ "prompt": "<user_prompt>", "model_id": "2-11", "options": { "prompt_optimization": true, "aspect_ratio": "16:9" } }' ``` Lines 199–211: ```bash curl -s -X POST https://api.pixwith.ai/api/task/create \ -H "Content-Type: application/json" \ -H "Api-Key: $PIXWITH_API_KEY" \ -d '{ "prompt": "<video_description>", "image_urls": ["<start_frame_url>", "<end_frame_url>"], "model_id": "2-11", "options": { "prompt_optimization": true, "aspect_ratio": "16:9" } }' ``` ### Technical Analysis The documented commands place user-controlled prompts and image URLs directly inside a single-quoted shell argument. The skill does not require these values to be encoded with a JSON serializer or passed through a mechanism that keeps data separate from shell syntax. If an implementation follows these examples by textual substitution, a value containing a single quote can terminate the quoted JSON argument. Subsequent shell metacharacters can then be interpreted as command syntax rather than request data. This issue applies to the following externally controlled values: - `<user_prompt>` - `<video_description>` - `<start_frame_url>` - `<end_frame_url>` JSON escaping alone is insufficient if the resulting JSON is subsequently embedded in shell source. Both JSON serialization and safe process argument handling are required. ### Attack Path 1. An attacker provides a crafted video prompt or image URL containing a single quote, shell separators, and an operating-system command. 2. The agent substitutes the supplied v ...[truncated 1386 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Do not construct JSON request bodies by inserting user-controlled text into shell command templates. 1. Use a real JSON serializer such as `jq`: ```bash request_file="$(mktemp)" trap 'rm -f "$request_file"' EXIT jq -n \ --arg prompt "$USER_PROMPT" \ --arg model_id "2-11" \ '{ prompt: $prompt, model_id: $model_id, options: { prompt_optimization: true, aspect_ratio: "16:9" } }' > "$request_file" curl -sS -X POST "https://api.pixwith.ai/api/task/create" \ -H "Content-Type: application/json" \ -H "Api-Key: $PIXWITH_API_KEY" \ --data-binary "@$request_file" ``` 2. Build `image_urls` as a JSON array through the serializer rather than interpolating URLs into JSON or shell source. 3. Prefer invoking HTTP clients through a structured process-execution API that passes each argument separately and does not invoke `/bin/sh`. 4. Apply the same safe construction pattern to all API-derived and user-controlled values, including prompts, image URLs, task IDs, upload URLs, and presigned form fields. 5. Validate expected value types and constraints before use, while treating validation as defense in depth rather than a replacement for safe serialization. 6. Create temporary request files with restrictive permissions and ensure they are removed reliably. 7. Add tests containing single quotes, double quotes, newlines, command separators, command substitutions, and other shell metacharacters to verify that they remain inert data. ]]>
