T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:117
- Finding
- Shell Command Injection Through User-Controlled voice_id## Vulnerability Details **File Location**: `SKILL.md`, lines 117–132 **Vulnerability Type**: Shell command injection caused by unsafe interpolation **Risk Level**: High ### Vulnerable Code ```bash Once the user provides their voice_id, synthesize a welcome message so they can hear their AI voice for the first time: Default preview text (warm and personal): > "你好!这是我的 AI 声音。从今天起,我可以用这个声音说任何我想说的话了。" ```bash curl -s -X POST https://api.senseaudio.cn/v1/t2a_v2 \ -H "Authorization: Bearer $SENSEAUDIO_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"model\": \"SenseAudio-TTS-1.0\", \"text\": \"你好!这是我的 AI 声音。从今天起,我可以用这个声音说任何我想说的话了。\", \"stream\": false, \"voice_setting\": { \"voice_id\": \"<VOICE_ID>\" }, \"audio_setting\": { \"format\": \"mp3\" } }" -o preview.json ``` ### Technical Analysis The workflow instructs the agent to accept a `voice_id` from the user and place it inside a JSON document embedded directly in a double-quoted shell argument. If the placeholder is replaced through direct textual interpolation, shell constructs in the supplied value can remain active. In particular, command substitution expressions such as `$(command)` and backtick expressions are evaluated inside double quotes before `curl` is executed. JSON escaping does not prevent shell evaluation. Merely surrounding the resulting JSON with double quotes is therefore insufficient to treat the user-provided identifier as data. Exploitation depends on an implementation following the documented substitution pattern directly rather than passing the identifier through a safe argument or structured JSON builder. ### Attack Path 1. An attacker supplies a crafted `voice_id` containing a shell command-substitution expression. 2. The agent substitutes that value directly for `<VOICE_ID>` in the documented shell command. 3. The shell evaluates the injected command substitution while const ...[truncated 940 chars]
- Remediation
- ## Remediation Suggestions - Do not construct JSON by interpolating user-controlled values into a shell command string. - Store the supplied identifier in a shell variable and use `jq --arg` to encode it as JSON data. - Validate `voice_id` against the provider's documented syntax, length, and character set before use. Validation should be defense in depth rather than the sole protection. - Pass the generated request through a file or standard input using `--data-binary`, avoiding shell re-evaluation. - Use `curl --fail --silent --show-error` so HTTP failures are reported reliably. - Avoid logging the API key or full authorization header. Example hardened construction: ```bash jq -n --arg voice_id "$VOICE_ID" '{ model: "SenseAudio-TTS-1.0", text: "你好!这是我的 AI 声音。从今天起,我可以用这个声音说任何我想说的话了。", stream: false, voice_setting: {voice_id: $voice_id}, audio_setting: {format: "mp3"} }' > request.json curl --fail --silent --show-error \ -X POST https://api.senseaudio.cn/v1/t2a_v2 \ -H "Authorization: Bearer $SENSEAUDIO_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @request.json \ -o preview.json ```
