T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/search-flights.sh:6
- Finding
- Unsafe JSON Construction in Flight Search Request## Vulnerability Details **File Location**: `scripts/search-flights.sh`, lines 6–14 and 18–23 **Vulnerability Type**: Improper JSON encoding and input validation **Risk Level**: Medium ### Vulnerable Code ```bash # Parameters DEP_COUNTRY="$1" ARR_COUNTRY="$2" IS_BUSINESS="$3" DEP_CITY="$4" ARR_CITY="$5" CURRENCY="$6" DEP_DATE="$7" SUB_QUERY="$8" # Make API call curl --silent --location --request POST \ 'https://ivguserprod.alipay.com/ivgavatarcn/api/v1/voyager/mcp/RECALL_flight' \ --header 'Content-Type: application/json' \ --data @- <<EOF {"depCountry":"${DEP_COUNTRY}","arrCountry":"${ARR_COUNTRY}","isBusiness":${IS_BUSINESS},"arrCity":"${ARR_CITY}","depCity":"${DEP_CITY}","currency":"${CURRENCY}","depDate":"${DEP_DATE}","subQuery":"${SUB_QUERY}"} EOF ``` ### Technical Analysis The script interpolates command-line arguments directly into a JSON document. Shell quoting protects the assignments from shell word splitting, but it does not perform JSON escaping. An input containing a double quote, backslash, control character, or JSON syntax can terminate its intended string and alter the outbound object. The `IS_BUSINESS` value is especially exposed because it is inserted as an unquoted JSON token without validation. Crafted input can therefore add fields, change field types, override the intended request structure, or make the payload invalid. This is request-body injection into the fixed Alipay+ flight-search endpoint. The observed code does not pass these values to `eval` or a shell command position, so the evidence does not establish local command execution. ### Attack Path 1. An attacker supplies crafted travel-search input that becomes one of the script arguments, such as `subQuery`, a city, or `isBusiness`. 2. The calling agent invokes `scripts/search-flights.sh` using that value. 3. The script inserts the value into the here-document without JSON encoding or schema validation. 4. The crafted value escapes its intended JSON field or changes t ...[truncated 839 chars]
- Remediation
- ## Remediation Suggestions Construct the request with a JSON-aware tool rather than string interpolation: ```bash #!/bin/bash set -euo pipefail if [ "$#" -ne 8 ]; then printf 'Usage: %s <depCountry> <arrCountry> <isBusiness> <depCity> <arrCity> <currency> <depDate> <subQuery>\n' "$0" >&2 exit 2 fi DEP_COUNTRY="$1" ARR_COUNTRY="$2" IS_BUSINESS="$3" DEP_CITY="$4" ARR_CITY="$5" CURRENCY="$6" DEP_DATE="$7" SUB_QUERY="$8" case "$IS_BUSINESS" in true|false) ;; *) printf 'isBusiness must be true or false\n' >&2 exit 2 ;; esac PAYLOAD=$(jq -n \ --arg depCountry "$DEP_COUNTRY" \ --arg arrCountry "$ARR_COUNTRY" \ --argjson isBusiness "$IS_BUSINESS" \ --arg arrCity "$ARR_CITY" \ --arg depCity "$DEP_CITY" \ --arg currency "$CURRENCY" \ --arg depDate "$DEP_DATE" \ --arg subQuery "$SUB_QUERY" \ '{ depCountry: $depCountry, arrCountry: $arrCountry, isBusiness: $isBusiness, arrCity: $arrCity, depCity: $depCity, currency: $currency, depDate: $depDate, subQuery: $subQuery }') curl --silent --show-error --fail --location --request POST \ 'https://ivguserprod.alipay.com/ivgavatarcn/api/v1/voyager/mcp/RECALL_flight' \ --header 'Content-Type: application/json' \ --data-binary "$PAYLOAD" ``` Additionally: - Validate the exact argument count before reading parameters. - Enforce `isBusiness` as the Boolean values `true` or `false`. - Validate `depDate` against the required `YYYY-MM-DD` format and reject impossible dates. - Apply reasonable length limits to free-text and location fields. - Restrict currency to supported currency codes where possible. - Use `curl --fail --show-error` so HTTP failures are surfaced reliably. - Add tests containing quotes, backslashes, newlines, and attempted JSON-property injection.
