T09 · Insecure Skill Coding Practices
Error
- Location
- gate_crossex.sh:55
- Finding
- Shell Command Injection Through eval-Based curl Invocation<![CDATA[ ## Vulnerability Details **File Location**: `gate_crossex.sh:55-66`, with attacker-controlled values originating at `gate_crossex.sh:70-76` and `gate_crossex.sh:114-135` **Vulnerability Type**: Shell command injection **Risk Level**: High ### Vulnerable Code ```bash # 发送 GET 请求 api_get() { local endpoint="$1" local params="$2" local url="${BASE_URL}${API_PREFIX}${endpoint}" if [ -n "$params" ]; then url="${url}?${params}" fi local headers=$(generate_signature "GET" "${API_PREFIX}${endpoint}" "$params" "") eval curl -s -X GET \"${url}\" $headers } # 发送 POST 请求 api_post() { local endpoint="$1" local data="$2" local url="${BASE_URL}${API_PREFIX}${endpoint}" local headers=$(generate_signature "POST" "${API_PREFIX}${endpoint}" "" "$data") eval curl -s -X POST \"${url}\" $headers -d \"${data}\" } ``` Attacker-controlled values can reach these functions through exported public functions: ```bash get_symbols() { local symbols="$1" local params="" if [ -n "$symbols" ]; then params="symbols=${symbols}" fi echo "📊 查询币对信息..." api_get "/rule/symbols" "$params" | jq '.' } ``` ```bash transfer_funds() { local currency="$1" local amount="$2" local from_account="$3" local to_account="$4" local data=$(cat <<EOF { "currency": "${currency}", "amount": "${amount}", "from": "${from_account}", "to": "${to_account}" } EOF ) echo "💸 资金划转: ${amount} ${currency} 从 ${from_account} 到 ${to_account}..." api_post "/wallet/transfers" "$data" | jq '.' } ``` ### Technical Analysis The script constructs curl commands as strings and executes them with `eval`. Unlike an ordinary command invocation, `eval` asks the shell to parse the generated command a second time. Values supplied through `symbols`, `currency`, `amount`, `from_account`, or `to_account` are embedded in that generated shell source. Embedded quotation marks, command substitutions, sepa ...[truncated 1990 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove every use of `eval`. 2. Construct curl arguments with a Bash array so each value remains a single argument: ```bash api_get() { local endpoint="$1" local params="$2" local url="${BASE_URL}${API_PREFIX}${endpoint}" local timestamp signature validate_endpoint "$endpoint" || return 1 if [[ -n "$params" ]]; then url="${url}?${params}" fi timestamp="$(date +%s)" signature="$(generate_signature_value \ "GET" "${API_PREFIX}${endpoint}" "$params" "" "$timestamp")" || return 1 curl_args=( --silent --show-error --fail-with-body --request GET --header "KEY: ${API_KEY}" --header "Timestamp: ${timestamp}" --header "SIGN: ${signature}" --header "Accept: application/json" --header "Content-Type: application/json" "$url" ) curl "${curl_args[@]}" } ``` 3. Use `curl --get --data-urlencode` rather than manually concatenating untrusted query parameters. 4. Build transfer JSON with a serializer rather than a heredoc: ```bash data="$(jq -n \ --arg currency "$currency" \ --arg amount "$amount" \ --arg from "$from_account" \ --arg to "$to_account" \ '{currency: $currency, amount: $amount, from: $from, to: $to}')" ``` 5. Validate symbols, currencies, account identifiers, and amounts against strict allowlists or documented formats. 6. Keep API endpoints internal and allowlist all supported endpoint paths. 7. Add regression tests containing quotation marks, command substitutions, separators, whitespace, and newline characters to verify that inputs cannot become shell syntax. ]]>
