T09 · Insecure Skill Coding Practices
- Location
scripts/loop.sh:14- Finding
Command Injection Through Unvalidated Crossfade Argument
- Content
View full analysis
/dev/null || ! command -v ffprobe &>/dev/null; then echo "ERROR: ffmpeg and ffprobe required. Install with: brew install ffmpeg" exit 1 fi for f in "$SRC_DIR"/*.mp4; do if [ ! -f "$f" ]; then echo "No .mp4 files found in $SRC_DIR" exit 1 fi filename=$(basename "$f") name="${filename%.mp4}" echo "Processing: $filename" dur=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$f") dur=${dur%.*} if [ -z "$dur" ] || [ "$dur" -lt 2 ]; then echo " Skipping $filename — duration <2s or unknown" continue fi half_dur=$((dur - XFADE)) echo " Duration: ${dur}s | Crossfade: ${XFADE}s | Output: ${name}_looped.mp4" ffmpeg -y -stream_loop 1 -i "$f" -i "$f" \ -filter_complex "[0:v]format=pix_fmts=yuva420p,fade=t=in:st=0:d=0.5:alpha=0[v0];[1:v]format=pix_fmts=yuva420p,fade=t=out:st=${half_dur}:d=${XFADE}:alpha=0[v1];[v0][v1]overlay=0:0:enable='between(t,${half_dur},'$(($half_dur + $XFADE))')'[out]" \ -map "[out]" \ -c:v libx264 -preset fast -crf 18 \ -t "$((dur * 2))" \ ``` ### Technical Analysis The third positional argument is assigned directly to `XFADE` without validating that it is a safe numeric value: ```bash XFADE="${3:-1}" ``` It is subsequently evaluated by Bash arithmetic expansion: ```bash half_dur=$((dur - XFADE)) ``` Bash recursively evaluates variable values used as arithmetic expressions. Arithmetic expressions can interpret variable and array-subscript syntax, and array subscripts may cause embedded command substitutions to be evaluated. Consequently, an attacker-controlled `XFADE` value containing a crafted arithmetic expression can cause a shell command to execute when the ...[truncated 2260 chars]- Remediation
View remediation
&2 exit 1 fi ``` 2. Apply an explicit reasonable upper bound to prevent invalid filters and excessive processing: ```bash if (( XFADE > 30 )); then echo "ERROR: crossfade_seconds must not exceed 30" >&2 exit 1 fi ``` 3. For each input file, verify that the crossfade is smaller than its duration before calculating `half_dur`: ```bash if (( XFADE >= dur )); then echo "Skipping $filename — crossfade must be shorter than the video" >&2 continue fi ``` 4. If fractional crossfade values such as `0.5` must be supported, do not pass them through Bash arithmetic expansion. Validate them with a strict decimal regular expression and perform calculations using a numeric tool such as `awk`, while passing values as data rather than source code: ```bash if [[ ! "$XFADE" =~ ^([0-9]+)(\.[0-9]+)?$ ]]; then echo "ERROR: invalid crossfade duration" >&2 exit 1 fi half_dur=$(awk -v d="$dur" -v x="$XFADE" 'BEGIN { printf "%.6f", d - x }') ``` 5. Reject negative values, exponent notation, shell metacharacters, whitespace, variable names, brackets, and all other non-numeric syntax. 6. Retain quoting around filesystem paths and FFmpeg arguments, and add automated regression tests that pass malicious arithmetic expressions as the third argument and verify that no command is executed. ]]>
