T09 · Insecure Skill Coding Practices
Error
- Location
- monthly-dca.sh:3
- Finding
- Arbitrary Command Execution Through Unvalidated Bash Arithmetic Input<![CDATA[ ## Vulnerability Details **File Location**: `monthly-dca.sh`, lines 3-12 **Vulnerability Type**: Bash arithmetic expression injection **Risk Level**: High ### Vulnerable Code ```bash BUDGET=${1:-500} # Default €500/month echo "💰 Monthly DCA Plan" echo "===================" echo "Budget: €$BUDGET" echo "" echo "Allocation:" echo "├── VWCE (70%): €$((BUDGET * 70 / 100))" echo "├── EIMI/IXUS (10%): €$((BUDGET * 10 / 100))" echo "├── BTC (10%): €$((BUDGET * 10 / 100))" echo "└── Cash buffer (10%): €$((BUDGET * 10 / 100))" ``` ### Technical Analysis The script accepts its first positional argument as `BUDGET` without checking that it is a decimal integer. It then references this variable inside four Bash arithmetic expansions. Bash recursively evaluates variable values as arithmetic expressions in arithmetic contexts. A malicious value containing an array-subscript expression can include command substitution, causing Bash to execute a command while resolving the arithmetic expression. Quoting the outer `echo` argument does not prevent this because the command execution occurs during arithmetic evaluation. Consequently, an attacker-controlled budget is not merely treated as financial data; it can be interpreted as executable Bash arithmetic syntax. ### Attack Path 1. An attacker supplies a crafted budget value or convinces a user or agent to invoke the script with that value. 2. The crafted value uses an arithmetic array-subscript expression containing command substitution, conceptually in the form: ```bash ./monthly-dca.sh 'x[$(ATTACKER_COMMAND)]' ``` 3. On line 9, Bash evaluates `BUDGET` while processing: ```bash $((BUDGET * 70 / 100)) ``` 4. Bash evaluates the embedded command substitution during arithmetic expression resolution. 5. The same unsafe variable is evaluated again on lines 10-12, so the injected command may execute multiple times. 6. The command runs with the operating-system identity, environment, fil ...[truncated 893 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Validate the argument before it reaches any arithmetic context. Accept only a bounded, non-negative decimal integer: ```bash #!/bin/bash set -euo pipefail BUDGET=${1:-500} if [[ ! $BUDGET =~ ^[0-9]+$ ]]; then printf 'Error: budget must be a non-negative whole number.\n' >&2 exit 1 fi if (( BUDGET > 100000000 )); then printf 'Error: budget exceeds the supported maximum.\n' >&2 exit 1 fi ``` Additional hardening measures: 1. Define an appropriate lower and upper bound based on the legitimate financial use case. 2. Reject signs, whitespace, decimal points, variable names, brackets, parentheses, and other arithmetic syntax. 3. Use a validated internal variable for all calculations rather than reusing raw input. 4. Add tests confirming rejection of array syntax, command substitutions, malformed numbers, negative values, and excessively large integers. 5. Consider performing calculations with a language or utility that parses input strictly as numeric data if decimal currency values must be supported. ]]>
