T09 · Insecure Skill Coding Practices
- Location
scripts/script.sh:96- Finding
Destructive find Expression Injection Through Off-by-One Argument Handling
- Content
View full analysis
" find "$2" -type f -exec sha256sum {} \; 2>/dev/null } ``` The relevant command dispatcher is: ```bash main() { local cmd="${1:-help}" case "$cmd" in create) shift; cmd_create "$@" ;; manifest) shift; cmd_manifest "$@" ;; verify) shift; cmd_verify "$@" ;; size) shift; cmd_size "$@" ;; list) shift; cmd_list "$@" ;; extract) shift; cmd_extract "$@" ;; help) cmd_help ;; version) cmd_version ;; *) die "Unknown command: $cmd (try help)" ;; esac } ``` ### Technical Analysis The dispatcher removes the command name with `shift` before forwarding the remaining arguments to `cmd_manifest`. Therefore, the directory supplied using the documented command syntax is available as `$1`. However, `cmd_manifest` incorrectly reads `$2`. This causes the documented invocation to fail and allows a second, attacker-controlled argument to be passed as the first effective operand to `find`. Because the script does not use end-of-options handling or otherwise validate the value, an option-like value can be interpreted as a `find` expression rather than as a directory. In particular, `-delete` is a destructive GNU `find` action. An invocation such as: ```bash scripts/script.sh manifest ignored -delete ``` results in `cmd_manifest` evaluating: ```bash find "-delete" -type f -exec sha256sum {} \; ``` On implementations that default to the current directory when no explicit starting path is present, `-delete` is interpreted as an expression. This can recursively delete entries beneath the current working directory. The precise behavior may vary between `find` implementatio ...[truncated 1837 chars]- Remediation
View remediation
" local dir="$1" [ -d "$dir" ] || die "Directory does not exist: $dir" find -- "$dir" -type f -exec sha256sum -- {} \; } ``` Apply the same argument-index correction to every handler: - Single-argument commands should consume `$1`. - Two-argument commands should consume `$1` and `$2`. - Commands should validate the exact number of arguments before operating. - Commands should use their validated local variables rather than accessing positional parameters again. - External utilities should receive `--` before attacker-controlled path operands when the utility supports it. - Option-like paths should be rejected or normalized for utilities that do not support `--`. - Automated tests should cover documented invocations, missing and extra arguments, paths containing spaces, and paths beginning with `-`. - Extraction and archive operations should also validate source and destination paths before modifying the filesystem. ]]>
