Back to skill

Security audit

voyager-travel-agent

Security checks for vulnerabilities and agentic risk

Overview

This travel skill sends flight and hotel search details to Alipay+ travel endpoints as disclosed, with some usability and input-validation risks but no evidence of hidden, destructive, persistent, or deceptive behavior.

Install only if you are comfortable sending travel search details to Alipay+ services. Before relying on results, confirm dates, currency, destination area, and booking links yourself; the hotel workflow may silently assume dates and nearby points of interest, and the flight script should be hardened for JSON input handling.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

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.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The code behavior is limited to searching flight tickets via a specific Voyager API endpoint (`RECALL_flight`). That aligns with part of the declared description (flight search), but the declared purpose presents the skill as a comprehensive travel agent covering hotels and itinerary planning as well. Those additional capabilities are not evidenced in this code chunk. There is no sign of unrelated or dangerous behavior, and the network access is consistent with travel search, but the description materially overstates the implemented functionality visible here.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
**External Service Calls**: This skill invokes tools that make network requests to Alipay+ travel service endpoints. User query data (dates, cities, search terms) will be transmitted to these external services.
**Privacy Notice**: By using this skill, you acknowledge that your travel search queries will be processed by Alipay+ servers to provide recommendations.

## Output Guidelines

Present results in markdown format.
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The usage examples include broad phrasings such as "Help me plan...", "what's the best itinerary?", and "Help me arrange..." without any explicit trigger constraints or exclusion conditions. In a markdown skill file, this can make activation boundaries unclear and increase the chance of unintended invocation from ordinary travel-related conversation.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The trigger condition 'when user asks about flights or tickets' is broad enough to activate on casual or ambiguous travel discussion, not just clear intent to use this skill. Over-broad invocation can cause unnecessary collection of travel parameters or tool calls, increasing the chance of unintended actions and context leakage in a booking-related workflow.

Natural-Language Policy Violations

Medium
Confidence
84% confidence
Finding
The examples and defaults embed Chinese-language queries and default HKD/CNY-related behavior without explicit user preference, which can silently bias locale, currency, and interpretation of travel requests. In a travel-booking context, this may lead to incorrect search parameters, misleading pricing, or user confusion, especially for international users.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- `brandNames`: List of hotel brand names
   - `subQuery`: **(Required)** Original query segment or user intention

2. **Handle Silent Defaults**: Apply defaults **silently** without asking user:
   - Missing checkInDate → today + 7 days
   - Missing checkOutDate → today + 8 days
   - **Missing city → ASK the user for city name (do NOT proceed without city)**
Confidence
90% confidence
Finding
The phrase 'apply defaults silently without asking user' delegates material decision-making to the agent without user awareness. In a hotel search workflow, autonomous assumptions about travel dates can affect search results, pricing, and suitability, making the agent act beyond the user's explicit instructions.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The guidance explicitly tells the agent to apply travel-date defaults silently, which can cause searches and recommendations to be based on dates the user never chose. In a travel-booking context, hidden assumptions about dates can mislead users, produce irrelevant availability/pricing, and potentially lead to downstream booking errors if the assumption is not surfaced and confirmed.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The instruction mandates a fixed Chinese response string ("search-hotels未返回符合要求的酒店") regardless of user language preference. This is a natural-language locale constraint and no opt-in, alternative language handling, or justification for the restriction is provided.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The instruction to infer 1-3 POIs when none are provided authorizes the agent to invent location intent and present hotel recommendations as if they match the user's needs. In a travel context, inferred landmarks can materially change hotel relevance, distance, and cost, so undisclosed assumptions can misdirect the user and degrade trust.

External Transmission

Medium
Category
Data Exfiltration
Content
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
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This shell script sends multiple user-provided inputs, including travel locations, date, currency, and free-form subQuery text, to a remote HTTPS endpoint via curl. While the file has a brief comment saying it searches via an API, it provides no explicit user-facing warning, confirmation, or disclosure that these inputs will be transmitted off-system.

External Transmission

Medium
Category
Data Exfiltration
Content
PARSED_JSON=$(echo "$QUERY_JSON" | jq .)

# Make API call
curl --silent --location --request POST \
  'https://ivguserprod.alipay.com/ivgavatarcn/api/v1/voyager/mcp/RECALL_hotel' \
  --header 'Content-Type: application/json' \
  --data "$PARSED_JSON"
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
This shell script performs an HTTP POST to a remote endpoint and transmits the user-supplied query payload, which may include travel details such as destination and dates. Although the header comments describe usage, the script provides no runtime notice, confirmation, or explicit warning that the input data will be sent to an external service.

Static analysis

No suspicious patterns detected.