T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:134
- Finding
- Unsafe interpolation of user-controlled and API-controlled values into shell commands<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:134-143`, `SKILL.md:155-156`, and `SKILL.md:225-235` **Vulnerability Type**: Shell command injection through unsafe construction of JSON request bodies **Risk Level**: Medium ### Vulnerable Code Text-to-image task creation: ```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": "0-41", "options": { "prompt_optimization": true, "resolution": "1K", "aspect_ratio": "1:1" } }' ``` Task-status polling: ```bash curl -s -X POST https://api.pixwith.ai/api/task/get \ -H "Content-Type: application/json" \ -H "Api-Key: $PIXWITH_API_KEY" \ -d '{"task_id": "<task_id>"}' ``` Image-to-image task creation: ```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": "<edit_instruction>", "image_urls": ["<image_url_1>", "<image_url_2>"], "model_id": "0-41", "options": { "prompt_optimization": true, "resolution": "1K", "aspect_ratio": "0" } }' ``` ### Technical Analysis The documented command templates place dynamic values such as the user prompt, edit instruction, image URLs, and API-returned task identifier inside single-quoted shell arguments. If an agent implements the instructions by directly replacing the placeholders before executing the command, an attacker-controlled single quote can terminate the shell-quoted JSON string. Subsequent shell metacharacters can then introduce an additional command. JSON escaping is not sufficient to prevent this issue because JSON and the shell have separate parsing contexts. A value must first be serialized safely as JSON and must then be passed to the shell without being reinterpreted as executable syntax. The task identifier is returned by the external API ...[truncated 2237 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not perform textual substitution inside shell-quoted JSON. Store every dynamic value in a shell variable and use a JSON serializer such as `jq`: ```bash request_body="$(jq -n \ --arg prompt "$USER_PROMPT" \ --arg model_id "0-41" \ --arg resolution "1K" \ --arg aspect_ratio "1:1" \ '{ prompt: $prompt, model_id: $model_id, options: { prompt_optimization: true, resolution: $resolution, aspect_ratio: $aspect_ratio } }')" 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_body" ``` 2. Serialize polling requests in the same manner: ```bash request_body="$(jq -n --arg task_id "$TASK_ID" '{task_id: $task_id}')" curl -sS -X POST "https://api.pixwith.ai/api/task/get" \ -H "Content-Type: application/json" \ -H "Api-Key: $PIXWITH_API_KEY" \ --data-binary "$request_body" ``` 3. Construct the `image_urls` array through the serializer rather than concatenating URL strings. Validate that each URL uses HTTPS and belongs to an explicitly authorized host before submitting it. 4. Treat all API response values as untrusted data even when they must be preserved exactly. “Use exactly as returned” should mean passing a value unchanged through safe variable and serialization APIs, not embedding it into executable shell text. 5. Prefer a language-native HTTP client with structured JSON encoding over generated shell commands where possible. 6. Add adversarial tests covering single quotes, double quotes, backslashes, newlines, command substitutions, semicolons, and shell metacharacters in prompts, task identifiers, and URLs. Verify that these values remain JSON data and cannot alter command structure. ]]>
