T09 · Insecure Skill Coding Practices
- Location
SKILL.md:88- Finding
Unsafe JSON Construction Allows Request-Body Injection
- Content
View full analysis
"$OUTFILE" echo "$(jq '.extra_info.audio_length' "${OUTFILE}.json")ms — $OUTFILE" } ``` ### Technical Analysis The function constructs the API request body by directly interpolating `TEXT`, `VOICE`, and `SPEED` into a manually quoted JSON document. These values are not JSON-encoded or validated before being inserted. `TEXT` contains LLM-generated story content influenced by user input. Double quotes, backslashes, literal control characters, or other JSON metacharacters within that content can terminate or alter the intended JSON string. For example, a generated text value resembling the following can introduce an additional property: ```text ", "unexpected_property": "attacker-controlled ``` The resulting request can contain attacker-influenced JSON structure rather than treating the entire value exclusively as story text. Ordinary dialogue containing quotation marks may also create malformed JSON and cause synthesis failures. Direct interpolation of `SPEED` without numeric validation similarly allows it to affect the surrounding JSON structure if the function is reused with an untrusted value. `VOICE` is placed inside a JSON string but is not encoded or restricted to the doc ...[truncated 2296 chars]- Remediation
View remediation
&2 return 1 ;; esac if ! [[ "$SPEED" =~ ^(0\.[0-9]+|1(\.0+)?)$ ]]; then echo "Invalid speed value" >&2 return 1 fi local PAYLOAD PAYLOAD=$(jq -n \ --arg text "$TEXT" \ --arg voice "$VOICE" \ --argjson speed "$SPEED" \ '{ model: "SenseAudio-TTS-1.0", text: $text, stream: false, voice_setting: { voice_id: $voice, speed: $speed }, audio_setting: { format: "mp3" } }') || return 1 if ! curl -sS --fail-with-body \ -X POST https://api.senseaudio.cn/v1/t2a_v2 \ -H "Authorization: Bearer $SENSEAUDIO_API_KEY" \ -H "Content-Type: application/json" \ --data-binary "$PAYLOAD" \ -o "${OUTFILE}.json"; then echo "SenseAudio API request failed" >&2 return 1 fi if ! jq -e '.data.audio | type == "string" and test("^[0-9A-Fa-f]+$")' \ "${OUTFILE}.json" >/dev/null; then echo "SenseAudio API returned an invalid audio payload" >&2 return 1 fi jq -r '.data.audio' "${OUTFILE}.json" | xxd -r -p > "$OUTFILE" || return 1 jq -r '"\(.extra_info.audio_length)ms — \($outfile)"' \ --arg outfile "$OUTFILE" "${OUTFILE}.json" } ``` Additional hardening measures: 1. Set explicit minimum and maximum limits for text length before transmission. 2. Validate that `SPEED` falls within the exact range supported by the API. 3. Use a restrictive `umask` if generated audio or API responses may contain sensitive content. 4. Remove temporary JSON response files after successfu ...[truncated 242 chars]
