T09 · Insecure Skill Coding Practices
- Location
scripts/bp.sh:12- Finding
Command Injection Through Unvalidated Bash Arithmetic Expressions
- Content
View full analysis
= 100000000 )); then printf "%.2f亿" "$(echo "scale=2; $n/100000000" | bc)" elif (( n >= 10000 )); then printf "%.1f万" "$(echo "scale=1; $n/10000" | bc)" else printf "%d" "$n" fi } ``` Additional unsafe arithmetic evaluations include: ```bash if (( monthly_rev > monthly_cost )); then bep_months=$(echo "scale=1; $invest / ($monthly_rev - $monthly_cost)" | bc) else bep_months="N/A (亏损状态)" fi ``` ```bash if (( invest > 0 )); then recovery=$(pct "$cum_profit" "$invest") else recovery="∞" fi ``` The affected values originate from command-line arguments without numeric validation: ```bash case "$CMD" in generate) # 解析参数: name industry invest monthly_rev monthly_cost growth IFS='|' read -ra ARGS <<< "$(echo "$INPUT" | sed 's/ */|/g')" name="${ARGS[0]:-我的项目}" industry="${ARGS[1]:-科技}" invest="${ARGS[2]:-1000000}" monthly_rev="${ARGS[3]:-200000}" monthly_cost="${ARGS[4]:-150000}" growth="${ARGS[5]:-15}" generate_bp "$name" "$industry" "$invest" "$monthly_rev" "$monthly_cost" "$growth" ;; ``` ### Technical Analysis Bash arithmetic contexts such as `(( n >= 100000000 ))` do not merely convert an arbitrary string into an integer. Bash treats the variable value as another arithmetic expression and recursively evaluates constructs within it. Certain arithmetic constructs, particularly array subscripts, can trigger command substitutions embedded in attacker-controlled values. The `generate` command accepts investment, revenue, cost, and growth values from command-line arguments. These values are not checked against a strict numeric format before being used in arithmetic expressions. ...[truncated 2154 chars]- Remediation
View remediation
&2 exit 2 fi } require_uint "investment" "$invest" require_uint "monthly revenue" "$monthly_rev" require_uint "monthly cost" "$monthly_cost" require_uint "growth rate" "$growth" ``` 2. If decimal values are required, define and enforce an explicit format such as `^[0-9]+([.][0-9]+)?$`. 3. Enforce sensible upper bounds to prevent integer overflow and denial-of-service behavior from extremely large numbers. 4. Do not treat failure from `bc` as a valid zero result. Return an error and terminate processing when a numeric expression cannot be parsed. 5. Avoid using untrusted variable contents directly in `(( ... ))`. Perform validation first and keep all subsequent arithmetic limited to validated canonical numbers. 6. Preserve command-line argument boundaries by using positional parameters or arrays directly rather than flattening all arguments into `INPUT="$*"` and reparsing them with `sed`. 7. Add regression tests containing arithmetic-expression payloads, array-subscript payloads, shell metacharacters, negative numbers, decimals, and oversized values. ]]>
