T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/audio_run.sh:35
- Finding
- Arbitrary Shell Command Execution Through Unsafe eval<![CDATA[ ## Vulnerability Details **File Location**: `scripts/audio_run.sh`, lines 35-45 **Vulnerability Type**: OS command injection **Risk Level**: Critical ### Vulnerable Code ```bash else echo "$cmd" fi } # 主逻辑 COMMAND="$1" OUTPUT="${2:-$DEFAULT_OUTPUT}" AUDIO_CMD=$(parse_natural_language "$COMMAND" "$OUTPUT") echo "[OpenClaw] 执行音频命令:$AUDIO_CMD" eval "$AUDIO_CMD" ``` ### Technical Analysis The script accepts its first command-line argument as `COMMAND` and passes it to `parse_natural_language`. If the input does not match one of the recognized audio-processing patterns, the parser returns the supplied value unchanged: ```bash else echo "$cmd" fi ``` The returned text is assigned to `AUDIO_CMD` and executed by `eval`. Because `eval` interprets shell operators, substitutions, redirections, pipelines, and command separators, an attacker can provide an arbitrary shell command instead of an audio-processing instruction. Recognized operations are also assembled as command strings using attacker-controlled input and output values before reaching `eval`. In particular, the output argument is inserted into generated FFmpeg commands without shell-safe argument handling. This creates additional injection opportunities through shell metacharacters in the output value. ### Attack Path 1. An attacker invokes the script with an unrecognized command containing a shell payload: ```bash ./scripts/audio_run.sh 'id > /tmp/pwned' ``` 2. The input does not match the supported Chinese audio-command patterns. 3. The fallback branch emits `id > /tmp/pwned` unchanged. 4. Command substitution assigns that text to `AUDIO_CMD`. 5. `eval "$AUDIO_CMD"` parses and executes the payload. 6. The output of `id` is written to `/tmp/pwned`, demonstrating arbitrary command execution. A malicious output argument can also inject commands into a recognized operation because the output is concatenated into an FFmpeg command string and subsequently evaluat ...[truncated 783 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove `eval` entirely. Never execute a string derived from user-controlled natural-language input. 2. Reject unsupported commands instead of returning and executing them: ```bash else printf '%s\n' "Unsupported audio operation" >&2 return 1 fi ``` 3. Invoke FFmpeg directly using separately quoted arguments: ```bash ffmpeg -y -i "$input" -vn -acodec mp3 "$output" ``` 4. Represent commands as Bash arrays if commands must be assembled dynamically: ```bash args=(ffmpeg -y -i "$input" -vn -acodec mp3 "$output") "${args[@]}" ``` 5. Validate all inputs: - Require input files to use explicitly supported media extensions. - Resolve and restrict paths to approved directories where appropriate. - Reject missing files and non-regular files. - Validate volume as a numeric value within an explicitly permitted range. - Reject output paths containing control characters and enforce an approved destination policy. 6. Use `set -euo pipefail` and quote every variable expansion, while recognizing that quoting alone does not make `eval` safe. 7. Add regression tests using command separators, substitutions, redirections, and crafted output paths to ensure they are treated as data rather than executable syntax. ]]>
