T09 · Insecure Skill Coding Practices
- Location
scripts/transcribe.sh:9- Finding
Original WAV Input Is Unconditionally Deleted After Transcription
- Content
View full analysis
/dev/null; then echo "Error: ffmpeg is required for non-WAV files. Install it with:" >&2 echo " macOS: brew install ffmpeg" >&2 echo " Linux: sudo apt install ffmpeg" >&2 exit 1 fi local tmp tmp="$(mktemp /tmp/qwen-asr-XXXXXX.wav)" ffmpeg -y -i "$input" -ar 16000 -ac 1 -f wav "$tmp" -loglevel error echo "$tmp" ;; esac } ... elif [ -n "${1:-}" ]; then INPUT="$(to_wav "$1")" trap 'rm -f "$INPUT"' EXIT 2>/dev/null || true qwen-asr -d "$MODEL_DIR" -i "$INPUT" --silent "${@:2}" ``` ### Technical Analysis The `to_wav` function returns two different types of paths through the same output channel: 1. For non-WAV input, it returns the path of a newly created temporary WAV file. 2. For WAV input, it returns the original caller-supplied path without creating a temporary file. The caller does not distinguish between these cases. It stores either result in `INPUT` and registers an unconditional `EXIT` trap that runs: ```bash rm -f "$INPUT" ``` Consequently, when the supplied input already has a `.wav` or `.WAV` extension, the cleanup handler deletes the original user file. The trap runs whenever the shell exits after registration, including when transcription succeeds, when `qwen-asr` fails, or when the script is interrupted by a trapped exit condition. Quoting prevents shell injection through the path, but it does not prevent destructive deletion of the selected file. ### Attack Path 1. A user or calling agent invokes the wrapper with a writable WAV file: ```bash bash scripts/transcribe.sh /home/user/recordings/meeting.wav ``` 2. `to_wav` i ...[truncated 1100 chars]- Remediation
View remediation
/dev/null 2>&1; then echo "Error: ffmpeg is required for non-WAV files." >&2 exit 1 fi TEMP_WAV="$(mktemp "${TMPDIR:-/tmp}/qwen-asr-XXXXXX.wav")" ffmpeg -y -i "$input" -ar 16000 -ac 1 -f wav \ "$TEMP_WAV" -loglevel error printf '%s\n' "$TEMP_WAV" ;; esac } ``` Because command substitution runs a function in a subshell in Bash, a more robust design would have `to_wav` assign the result to a caller-visible variable or perform conversion directly in the main shell. Additional hardening should include: - Validate that the input exists and is a regular readable file. - Use `rm -f -- "$TEMP_WAV"` to terminate option parsing explicitly. - Register cleanup immediately after creating the temporary file. - Add regression tests proving that original WAV inputs still exist after successful and failed transcription. - Document temporary-file behavior and data-retention expectations. ]]>
