T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/script.sh:104
- Finding
- Search-Term Option Injection Allows Out-of-Scope File Access<![CDATA[ ## Vulnerability Details **File Location**: `scripts/script.sh`, lines 104-119 **Vulnerability Type**: Argument and option injection into `grep` **Risk Level**: Medium ### Vulnerable Code ```bash _search() { local term="${1:?Usage: podcast-notes search <term>}" echo "Searching for: $term" local found=0 for f in "$DATA_DIR"/*.log; do [ -f "$f" ] || continue local matches=$(grep -i "$term" "$f" 2>/dev/null || true) if [ -n "$matches" ]; then echo " --- $(basename "$f" .log) ---" echo "$matches" | while read -r line; do echo " $line" found=$((found + 1)) done fi done [ $found -eq 0 ] && echo " No matches found." } ``` ### Technical Analysis The user-controlled `term` is passed to `grep` without terminating option parsing. Quoting the variable prevents shell word splitting but does not prevent `grep` from interpreting a value beginning with a hyphen as an option. For example, a search term in the form `-f/path/to/file` may be interpreted as a `grep` pattern-file option rather than as a literal search term. This causes `grep` to read a user-selected, process-readable file outside the declared podcast data directory and use its contents as search patterns. The redirected standard error limits direct error disclosure, but matching behavior and output may still provide a content oracle. Selecting a device or unusually large file as a pattern source may also consume excessive CPU, memory, or I/O resources. ### Attack Path 1. An attacker supplies a crafted search term beginning with a valid `grep` option, such as `-f/path/to/readable/file`. 2. The `search` dispatch passes that value to `_search`. 3. `_search` executes `grep -i "$term" "$f"` for every podcast log. 4. `grep` interprets the term as an option and reads the attacker-selected file as a pattern source. 5. Any resulting matches are printed, potentially revealing whethe ...[truncated 713 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Terminate option parsing and use literal fixed-string matching unless regular expressions are explicitly required: ```bash local matches matches=$(grep -iF -- "$term" "$f" 2>/dev/null || true) ``` Additional hardening should include: 1. Reject empty search terms explicitly. 2. Use `--` before every user-controlled positional argument passed to command-line utilities. 3. Prefer `grep -F` to avoid unintended regular-expression interpretation. 4. Consider limiting the maximum search-term length to reduce resource-exhaustion risk. 5. Add tests for terms such as `-f/etc/passwd`, `--help`, `-e`, and strings containing regular-expression metacharacters. ]]>
