T09 · Insecure Skill Coding Practices
- Location
- scripts/play-local-audio.sh:71
- Finding
- Configuration-Controlled Arbitrary Command Execution Through Custom Playback Backend<![CDATA[ ## Vulnerability Details **File Location**: `scripts/play-local-audio.sh:25-42, 71-75` **Vulnerability Type**: Configuration-driven arbitrary command execution **Risk Level**: High ### Vulnerable Code ```bash if [[ -f "$CFG" && ( -z "$BACKEND" || -z "$DEVICE" ) ]]; then mapfile -t vals < <(python3 - "$CFG" <<'PY' import json,sys try: c=json.load(open(sys.argv[1])) p=c.get('playback',{}) print(p.get('backend','')) print(p.get('device','')) except Exception: print('') print('') PY ) [[ -z "$BACKEND" ]] && BACKEND="${vals[0]:-}" [[ -z "$DEVICE" ]] && DEVICE="${vals[1]:-}" fi ``` ```bash *) if command -v "$BACKEND" >/dev/null 2>&1; then exec "$BACKEND" "$FILE" fi echo "unknown/unavailable backend: $BACKEND" >&2 exit 1 ;; ``` ### Technical Analysis The playback backend can be loaded from `config/tts-queue.json`. Although known backends are handled by dedicated branches, the default branch permits any value that resolves through `command -v`. The selected executable is then launched as: ```bash exec "$BACKEND" "$FILE" ``` Shell metacharacters inside `BACKEND` are not directly interpreted because the variable is quoted. Nevertheless, the absence of an executable allowlist creates an arbitrary program execution primitive. An attacker can select an interpreter such as `bash`, `python3`, or another executable available through `PATH`. The supplied audio-file argument then becomes input to that executable. For example, if `playback.backend` is set to `bash` and the requested “audio file” is an existing shell script, the script is executed rather than played. ### Attack Path 1. The attacker obtains the ability to modify `config/tts-queue.json`, influence first-run setup values, or otherwise control the playback backend argument. 2. The attacker sets `playback.backend` to an interpreter or attacker-controlled executable available through `PATH`. 3. The attacker creates or selects an existing file that passes the script's ` ...[truncated 773 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove support for unrestricted custom backend executable names. 2. Enforce a strict allowlist containing only explicitly supported values: - `mpv` - `ffplay` - `paplay` - `afplay` - `powershell-soundplayer` 3. Reject all other backend values with a nonzero exit status. 4. Validate configuration when it is created and again when it is consumed. 5. If custom backends are required, define them through administrator-controlled configuration and require: - A canonical absolute executable path. - Ownership and permission checks. - Rejection of interpreters and writable executable paths. - A fixed argument template that cannot treat the audio file as source code. 6. Add tests confirming that values such as `bash`, `python3`, and arbitrary executables are rejected. ]]>
