T09 · Insecure Skill Coding Practices
- Location
scripts/search-flights.sh:6- Finding
Unsafe JSON Construction in Flight Search Request
- Content
View full analysis
Vulnerability Details
File Location:
scripts/search-flights.sh, lines 6–14 and 18–23
Vulnerability Type: Improper JSON encoding and input validation
Risk Level: MediumVulnerable 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}"} EOFTechnical 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_BUSINESSvalue 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
evalor a shell command position, so the evidence does not establish local command execution.Attack Path
- An attacker supplies crafted travel-search input that becomes one of the script arguments, such as
subQuery, a city, orisBusiness. - The calling agent invokes
scripts/search-flights.shusing that value. - The script inserts the value into the here-document without JSON encoding or schema validation.
- The crafted value escapes its intended JSON field or changes t ...[truncated 839 chars]
- An attacker supplies crafted travel-search input that becomes one of the script arguments, such as
- Remediation
View 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
isBusinessas the Boolean valuestrueorfalse. - Validate
depDateagainst the requiredYYYY-MM-DDformat 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-errorso HTTP failures are surfaced reliably. - Add tests containing quotes, backslashes, newlines, and attempted JSON-property injection.
