T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/small-cap-scanner.sh:10
- Finding
- Arbitrary Command Execution Through Unvalidated Arithmetic Input<![CDATA[ ## Vulnerability Details **File Location**: `scripts/small-cap-scanner.sh`, lines 10-22 **Vulnerability Type**: Bash arithmetic-expression injection **Risk Level**: High ```bash PAGES="${5:-3}" # Number of pages to scan echo "🔍 Ori Small-Cap Scanner" echo "═══════════════════════════════════════════════════════════════════════════════" echo "Chain: $CHAIN | Max FDV: \$$MAX_FDV | Min Liquidity: \$$MIN_LIQUIDITY" echo "Min Buy Ratio: $MIN_BUY_RATIO | Pages: $PAGES" echo "───────────────────────────────────────────────────────────────────────────────" echo "" OPPORTUNITIES=() TOTAL_SCANNED=0 for ((page=1; page<=PAGES; page++)); do ``` ### Technical Analysis The fifth positional argument is assigned directly to `PAGES` without validating that it contains only a bounded positive integer. The value is subsequently evaluated in the Bash arithmetic expression: ```bash ((page=1; page<=PAGES; page++)) ``` Bash recursively interprets variable values used in arithmetic contexts as arithmetic expressions. An attacker-controlled value can therefore contain array-subscript syntax with command substitution. The command substitution may be executed by Bash while evaluating the loop condition. A representative proof-of-concept argument is: ```bash ./scripts/small-cap-scanner.sh base 5000000 10000 1.3 \ 'x[$(touch /tmp/token-scout-poc)]' ``` When `PAGES` is evaluated as part of the loop condition, the embedded command substitution can create `/tmp/token-scout-poc`. A malicious payload could replace `touch` with another command available to the invoking process. Although several other script arguments are also accepted without strict validation, the confirmed command-execution sink is the use of `PAGES` in the Bash arithmetic loop. ### Attack Path 1. An attacker supplies or recommends a crafted fifth argument to `small-cap-scanner.sh`. 2. The script stores the argument unchanged in `PAGES`. 3. Execution reaches the arithmetic `for` loop at l ...[truncated 1247 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Validate every argument before it reaches an arithmetic context. Require `PAGES` to be a decimal integer and impose a reasonable upper bound: ```bash PAGES="${5:-3}" if ! [[ "$PAGES" =~ ^[0-9]+$ ]] || (( PAGES < 1 || PAGES > 100 )); then echo "Error: pages must be an integer between 1 and 100" >&2 exit 2 fi ``` After validation, copy the value into an explicitly numeric variable and use that variable in the loop: ```bash PAGE_LIMIT=$((10#$PAGES)) for ((page=1; page<=PAGE_LIMIT; page++)); do # Scan page done ``` The `10#` prefix forces decimal interpretation and avoids accidental octal handling for values with leading zeroes. Apply equivalent allow-list validation to all externally supplied parameters: - Restrict `CHAIN` to the documented supported network identifiers. - Require `MAX_FDV` and `MIN_LIQUIDITY` to be bounded non-negative integers. - Require `MIN_BUY_RATIO` to match a narrowly defined decimal-number format. - Reject unexpected extra arguments. - Avoid placing untrusted text directly into Bash arithmetic expressions or dynamically evaluated `bc` programs. For additional hardening, enable strict shell behavior after argument validation: ```bash set -euo pipefail ``` Add regression tests that pass arithmetic metacharacters, array syntax, command substitutions, negative values, excessively large values, and non-numeric strings. The tests should verify that all such inputs are rejected before the loop condition is evaluated. ]]>
