T09 · Insecure Skill Coding Practices
Error
- Location
- bin/voice-agent.sh:106
- Finding
- Configuration-Based Arbitrary Command Execution Through eval<![CDATA[ ## Vulnerability Details **File Location**: `bin/voice-agent.sh:106-110` **Vulnerability Type**: Shell command injection through unsafe configuration expansion **Risk Level**: High ### Vulnerable Code ```bash WHISPER_DIR=$(grep "whisper_dir:" "$CONFIG_FILE" | sed 's/.*: *//;s/["'\'']//g') if [ -z "$WHISPER_DIR" ]; then WHISPER_DIR="$HOME/.local/whisper.cpp" fi WHISPER_DIR=$(eval echo "$WHISPER_DIR") ``` The affected setting is explicitly presented as user-editable: ```yaml # config/voices.yaml:12-13 # Whisper.cpp installation path whisper_dir: ~/.local/whisper.cpp ``` ### Technical Analysis The script reads `whisper_dir` from `config/voices.yaml` and interpolates the resulting string into an `eval` command. Unlike normal variable expansion, `eval` reparses its arguments as shell syntax. Consequently, command substitutions, shell operators, redirections, and other shell constructs embedded in the YAML value are interpreted and executed. The use of `eval` is unnecessary for expanding a leading tilde. The Python STT implementation already performs safe home-directory expansion with `os.path.expanduser`, but the shell dependency check independently processes the same setting using unsafe shell evaluation. ### Attack Path 1. An attacker obtains the ability to modify the installed Skill configuration, such as through a compromised update, writable shared installation, malicious archive replacement, or another local integrity failure. 2. The attacker changes the setting to a value containing shell syntax, for example: ```yaml whisper_dir: '$(touch /tmp/voice-agent-eval-executed)' ``` 3. The victim starts `bin/voice-agent.sh` in any normal operating mode. 4. `check_dependencies` reads the malicious value. 5. `eval echo "$WHISPER_DIR"` reparses and executes the command substitution. 6. A real payload would execute with all privileges and filesystem access held by the user running the Skill. ### Impact Assessment Successful exploitati ...[truncated 445 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Remove `eval` completely. - Parse YAML with `yaml.safe_load` rather than `grep` and `sed`. - Expand only a documented leading `~/` prefix without evaluating shell syntax. - Validate that the resulting value is a string and resolves to an expected directory. - Consider resolving and constraining the path with `realpath` before use. - Ensure installed configuration files are writable only by the owning user. A safe shell approach for the documented use case is: ```bash case "$WHISPER_DIR" in "~") WHISPER_DIR="$HOME" ;; "~/"*) WHISPER_DIR="$HOME/${WHISPER_DIR#~/}" ;; esac ``` Preferably, use the same Python YAML-loading implementation as `lib/stt.py` so that shell parsing is not required. ]]>
