T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/nearby.sh:19
- Finding
- Bash Arithmetic Expression Injection Through the Radius Argument<![CDATA[ ## Vulnerability Details **File Location**: `scripts/nearby.sh:19-42` **Vulnerability Type**: Bash arithmetic expression injection **Risk Level**: High ### Vulnerable Code ```bash lng="" lat="" radius="1000" cti="" arrange="E" num="20" page="1" while [[ $# -gt 0 ]]; do case "$1" in --lng) lng="$2"; shift 2;; --lat) lat="$2"; shift 2;; --radius) radius="$2"; shift 2;; --content-type-id) cti="$2"; shift 2;; --arrange) arrange="$2"; shift 2;; --num) num="$2"; shift 2;; --page) page="$2"; shift 2;; -h|--help) sed -n '2,14p' "$0" | sed 's/^# \{0,1\}//' exit 0;; *) echo "error: unknown flag '$1'" >&2; exit 64;; esac done [[ -z "$lng" || -z "$lat" ]] && { echo "error: --lng and --lat are required." >&2; exit 64; } [[ -n "$cti" ]] && valid_content_type "$cti" if (( radius > 20000 )); then echo "error: --radius max is 20000 (got $radius)." >&2; exit 64 fi ``` ### Technical Analysis The value supplied through `--radius` is stored without numeric validation and then evaluated directly in a Bash arithmetic context: ```bash (( radius > 20000 )) ``` Bash arithmetic expressions are not equivalent to safely parsing an integer. Variable values can be recursively interpreted as arithmetic syntax. Crafted expressions containing array subscripts and command substitutions can therefore cause shell commands to execute during arithmetic evaluation. An illustrative malicious value is: ```bash 'x[$(touch /tmp/nearby-injection)0]' ``` When Bash resolves this value as an arithmetic expression, the command substitution can execute before the numeric comparison completes. Quoting the value when it is assigned does not prevent its subsequent interpretation by `(( ... ))`. ### Attack Path 1. An attacker gains control over an argument passed to `nearby.sh`, such as through an AI-generated tool invocation, web req ...[truncated 1480 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Validate the radius as a decimal integer before using any arithmetic expression: ```bash [[ "$radius" =~ ^[0-9]+$ ]] || { echo "error: --radius must be a positive integer." >&2 exit 64 } if (( 10#$radius < 1 || 10#$radius > 20000 )); then echo "error: --radius must be between 1 and 20000." >&2 exit 64 fi ``` The `10#` prefix forces decimal interpretation and avoids unintended octal handling for values with leading zeroes. Apply strict validation to the other numeric arguments as well: - `--lng`: decimal number within `-180` to `180`. - `--lat`: decimal number within `-90` to `90`. - `--num`: positive integer with a documented upper bound. - `--page`: positive integer. - Area and district codes: digits only where required. Argument handlers should also verify that a value exists before reading `$2`, so malformed invocations produce a controlled usage error rather than an unbound-variable failure. ]]>
