T09 · Insecure Skill Coding Practices
Error
- Location
- research_assistant.sh:56
- Finding
- Arbitrary Command Execution Through Unvalidated --max Arithmetic Expression<![CDATA[ ## Vulnerability Details **File Location**: `research_assistant.sh`, lines 16 and 56 **Vulnerability Type**: Shell arithmetic expression injection leading to command execution **Risk Level**: High ### Vulnerable Code ```bash --max) MAX="$2"; shift 2 ;; ``` The unvalidated value is subsequently used as a Bash arithmetic operand: ```bash if [[ "$MAX" -gt 0 && "$count" -ge "$MAX" ]]; then break; fi ``` ### Technical Analysis The `--max` argument accepts arbitrary text without verifying that it is a non-negative decimal integer. Its value is later passed to the `-gt` and `-ge` arithmetic comparison operators inside `[[ ... ]]`. Bash interprets operands to arithmetic operators as arithmetic expressions rather than inert strings. Arithmetic expressions can recursively resolve variable and array references. Malicious syntax containing an array subscript and command substitution can therefore cause Bash to execute a command while evaluating the comparison. Quoting `"$MAX"` does not make an attacker-controlled arithmetic expression safe. The value must be validated before it reaches an arithmetic evaluation context. For example, an attacker-controlled argument can use a structure similar to: ```bash ./research_assistant.sh --max 'x[$(touch /tmp/research-assistant-poc)0]' --dry-run ``` When the `--max` value is evaluated by the numeric comparison, Bash may execute the embedded `touch` command. The proof-of-concept command only creates a harmless file; other commands would run with the script process's privileges. ### Attack Path 1. An attacker gains control over arguments passed to `research_assistant.sh`. This may occur through an automation layer, agent-generated invocation, wrapper script, or another interface that forwards an untrusted maximum value. 2. The attacker supplies a crafted `--max` value containing Bash arithmetic syntax and command substitution. 3. The option parser stores the value in `MAX` without validating its format. 4. Process ...[truncated 1311 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Validate `--max` immediately after reading it and before any arithmetic operation. Accept only ASCII decimal digits: ```bash --max) [[ $# -ge 2 ]] || { echo "Missing value for --max" >&2 exit 1 } MAX="$2" [[ "$MAX" =~ ^[0-9]+$ ]] || { echo "Invalid --max value: expected a non-negative integer" >&2 exit 1 } shift 2 ;; ``` For defense in depth, validate all enumerated and value-bearing options after parsing: ```bash [[ "$MAX" =~ ^[0-9]+$ ]] || { echo "Invalid --max value" >&2 exit 1 } case "$MODE" in append|prepend) ;; *) echo "Invalid --mode: expected append or prepend" >&2 exit 1 ;; esac ``` Additional hardening measures: 1. Check that each option requiring a value has another argument available before reading `$2`. 2. Do not place untrusted strings in Bash arithmetic contexts. 3. If this script is invoked by an agent, service, or wrapper, pass arguments as a structured argument array rather than constructing a shell command string. 4. Add regression tests that reject arithmetic syntax, command substitutions, signs, whitespace, and non-decimal values for `--max`. 5. Run the script with the minimum filesystem and application permissions needed to process Bear notes. ]]>
