T09 · Insecure Skill Coding Practices
- Location
scripts/duf.sh:42- Finding
GNU find Expression Injection Through Unvalidated Path Arguments
- Content
View full analysis
/dev/null | sort -rh | head -"$n" ``` ```bash find "$path" -type f -size +"$size" -exec ls -lh {} \; 2>/dev/null | awk '{print $5, $9}' | sort -rh | head -20 ``` ```bash find "$path" -type f 2>/dev/null | while read f; do echo "$(stat -c%s "$f" 2>/dev/null || stat -f%z "$f" 2>/dev/null) $(basename "$f")" done | sort | uniq -d | head -20 ``` ### Technical Analysis The `top`, `find-big`, and `duplicates` commands pass a user-controlled path directly to GNU `find`. Shell quoting prevents shell metacharacter expansion, but it does not stop `find` from interpreting an argument beginning with `-` as an expression or action. In particular, GNU `find` supports the destructive `-delete` action. When a supplied path is parsed as an expression rather than a filesystem search root, a value such as `-delete` can cause `find` to operate on its implicit current-directory root and delete matching entries. The risk is especially severe because the script does not validate that the path exists, reject option-like values, or convert relative paths into an unambiguous form such as `./path`. The same unsafe path-handling pattern occurs in three command branches: - `top`: line 42 - `find-big`: line 46 - `duplicates`: line 50 ### Attack Path 1. An attacker identifies or influences a directory from which the skill will be executed. 2. The attacker causes an affected command to receive `-delete` as its path argument. For example: ```bash scripts/duf.sh top 10 -delete ``` 3. The script passes `-delete` directly to GNU `find`: ```bash find "-delete" -type f -exec du -h {} + ``` 4. On a GNU `find` implementation that parses this as a `find` expression with an implicit current-directory search root, `-del ...[truncated 997 chars]- Remediation
View remediation
&2 return 1 ;; esac if [[ ! -d "$input" ]]; then echo "Error: directory does not exist: $input" >&2 return 1 fi if [[ "$input" != /* && "$input" != ./* && "$input" != ../* ]]; then input="./$input" fi printf '%s\n' "$input" } ``` Use the validated result before each `find` call: ```bash path="$(validate_directory "${2:-.}")" || exit 1 find "$path" -type f -exec du -h {} + ``` Also validate related arguments: ```bash [[ "$n" =~ ^[1-9][0-9]*$ ]] || { echo "Error: count must be a positive integer" >&2 exit 1 } [[ "$size" =~ ^[1-9][0-9]*[bcwkMGTPE]?$ ]] || { echo "Error: invalid size expression" >&2 exit 1 } ``` Add regression tests confirming that values such as `-delete`, `-exec`, `-ok`, and other expression-like arguments are rejected without modifying test files. ]]>
