T09 · Insecure Skill Coding Practices
- Location
scripts/resign.sh:3- Finding
Unquoted Shell Expansion Enables Word Splitting and Pathname Disclosure
- Content
View full analysis
/dev/null || true; INPUT="$*" python3 -c ' import sys from datetime import datetime,timedelta cmd=sys.argv[1] if len(sys.argv)>1 else "help" inp=" ".join(sys.argv[2:]) # ... ' "$CMD" $INPUT ``` The complete vulnerable operation is the final command invocation: ```bash ' "$CMD" $INPUT ``` ### Technical Analysis The script initially stores command-line input in `INPUT` using `"$*"`, but later expands `$INPUT` without quotation marks. Bash consequently applies word splitting and pathname expansion to the value before passing it to Python. Input containing wildcard characters such as `*`, `?`, or bracket expressions may therefore be replaced by matching filenames from the script's current working directory. Input boundaries are also lost, so quoted multiword values are reconstructed and split again. Shell operators embedded in the variable are not reparsed as shell syntax, so this issue does not directly provide arbitrary command execution. However, it can disclose local filenames through generated output, alter argument semantics, and produce unexpected failures. ### Attack Path 1. An attacker controls or influences an argument passed to `scripts/resign.sh`. 2. The attacker includes a pathname expansion pattern, for example: ```bash scripts/resign.sh generate '*' ExampleCorp 2 ``` 3. `INPUT` contains the literal supplied arguments. 4. At line 45, unquoted `$INPUT` is subject to pathname expansion in the current directory. 5. Matching local filenames are passed to the embedded Python program. 6. The Python program joins and parses those expanded values, potentially including local filenames in the generated resignation letter or causing values to be assigned to unintended fields. ### Impact Assessment The issue executes with the ...[truncated 559 chars]- Remediation
View remediation
/dev/null || true python3 -c ' import sys from datetime import datetime, timedelta cmd = sys.argv[1] if len(sys.argv) > 1 else "help" inp = " ".join(sys.argv[2:]) # ... ' "$CMD" "$@" ``` Additional hardening measures: 1. Validate the expected argument count separately for every command. 2. Parse `weeks` using explicit validation and return a controlled error for nonnumeric input. 3. Avoid converting structured command arguments into a single whitespace-delimited string. 4. Add tests using spaces and wildcard characters such as `*`, `?`, and `[a-z]`. 5. Run ShellCheck and address warnings such as SC2086 for unquoted expansions. ]]>
