Back to skill

Security audit

China Travel Planner

Security checks for vulnerabilities and agentic risk

Overview

The skill is mainly a disclosed China travel planner, but its optional page-deployment tooling can modify and publish a Git repository with weak safeguards.

Use the planning and local page-generation features only with trip details you are comfortable putting in files. Do not run the GitHub Pages deploy command unless you are in a clean, dedicated repository, have reviewed the exact files and remote target, and are comfortable making the itinerary public.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
page-generator/scripts/tpf-cli.py:192
Finding

GitHub Pages deployment destructively modifies the active Git working tree

Content
View full analysis
Remediation
View remediation
``` Alternatively, use a dedicated temporary Git repository containing only the generated artifacts. 2. Never run `git rm -rf .` in the primary working tree. 3. Check repository status before deployment: ```bash git status --porcelain ``` Refuse deployment when local changes exist unless the user explicitly selects a safe override. 4. Copy and stage only allowlisted artifacts, such as: - `index.html` - `trip-data.json` - Explicitly required static assets 5. Avoid `git add .`; pass exact artifact paths to `git add`. 6. Display the resolved remote URL, branch, and files to be published, then require explicit confirmation before pushing. 7. Use `check=True` for restoration operations and report restoration failures prominently. 8. Add a dry-run mode that reports all Git and filesystem changes without modifying the repository. 9. Preserve and clean up temporary worktrees in a guarded `finally` block without altering the caller's checked-out branch. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
page-generator/scripts/tpf-init.sh:22
Finding

Unvalidated project name permits path traversal outside the examples directory

Content
View full analysis
" echo "Example: bash tpf-init.sh hangzhou-2026-05" exit 1 fi PROJECT_NAME="$1" PROJECT_DIR="$FRAMEWORK_DIR/examples/$PROJECT_NAME" if [ -d "$PROJECT_DIR" ]; then echo "Error: $PROJECT_DIR already exists" exit 1 fi echo "Creating project: $PROJECT_NAME" mkdir -p "$PROJECT_DIR/data" # ── Create index.html ── cat > "$PROJECT_DIR/index.html" << 'HTMLEOF' ``` The same attacker-influenced directory is subsequently used for additional writes: ```bash cat > "$PROJECT_DIR/data/trip-data.json" << 'JSONEOF' ``` ```bash cat > "$PROJECT_DIR/README.md" << MDEOF ``` ### Technical Analysis The script treats its first argument as a safe project-name component but does not reject path separators or `..` traversal components. Shell quoting prevents command injection, but it does not prevent filesystem path traversal. For example, a value such as `../../new-project` produces a path equivalent to: ```text /examples/../../new-project ``` After path normalization, the target is outside the intended `examples` directory. If the selected final directory does not already exist, the script creates it and writes predictable files into it. The existing-directory check reduces direct overwrite of an existing directory, but it does not enforce containment and does not prevent arbitrary creation of a new directory elsewhere within the invoking user's writable filesystem. ### Attack Path 1. An attacker, untrusted automation, or malformed Agent-generated value supplies a project name containing traversal components, such as `../../new-project`. 2. The script concatenates the value with `FRAMEWORK_DIR/examples`. 3. The operating system resolves the `..` components outside the exampl ...[truncated 763 chars]
Remediation
View remediation
&2 exit 1 fi ``` 2. Explicitly reject: - `/` and `\` - `..` - Empty names - Control characters - Leading hyphens if later commands could interpret the name as an option 3. Resolve the destination to a canonical path and verify that it is a child of the canonical examples directory before creating it. 4. Create the project directory atomically and fail if it already exists: ```bash mkdir "$PROJECT_DIR" mkdir "$PROJECT_DIR/data" ``` 5. Avoid `mkdir -p` for the final untrusted directory because it can silently create a traversal-selected hierarchy. 6. Add tests covering names such as: - `../../outside` - `name/subdirectory` - `../examples2` - Empty and control-character-containing values ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/fetch_subway_data.py:9
Finding

Metro network data is retrieved over unauthenticated plaintext HTTP

Content
View full analysis
str: resp = requests.get(INDEX_URL, headers=HEADERS, timeout=20) resp.raise_for_status() resp.encoding = "utf-8" return resp.text ``` ```python def fetch_city_detail(city_id: str, cityname: str) -> Dict: url = DETAIL_URL.format(city_id=city_id, cityname=cityname) resp = requests.get(url, headers=HEADERS, timeout=20) resp.raise_for_status() data = resp.json() return data ``` ### Technical Analysis Both the city index and detailed metro data are retrieved using HTTP rather than HTTPS. HTTP does not authenticate the server and does not protect response integrity. An on-path attacker can alter the index HTML used to resolve city identifiers or replace the detailed JSON response. The code accepts the response after status checking and JSON parsing, without cryptographic verification or comprehensive schema and plausibility validation. The attacker-controlled response is normalized and used as planning input. This is a data-integrity vulnerability rather than a direct local code-execution vulnerability because the response is parsed as data and is not passed to `eval`, a shell, or another executable interpreter. ### Attack Path 1. A user or Agent invokes `fetch_subway_data.py`, directly or through trip generation with metro support. 2. The script sends HTTP requests to the AMap endpoints. 3. An attacker controlling or observing the local network, proxy, gateway, or DNS path intercepts the requests. 4. Th ...[truncated 904 chars]
Remediation
View remediation

T03 · Remote Payload Retrieval and Execution

Warning
Location
page-generator/templates/trip-page-tailwind.html:7
Finding

Generated pages execute mutable third-party JavaScript from an unpinned CDN

Content
View full analysis
``` The initialization script emits the same runtime dependency into newly generated projects: ```html 旅行计划 ``` ### Technical Analysis Every generated page loads and executes JavaScript from `cdn.tailwindcss.com` when opened. The URL is not tied to an immutable version, and the page does not specify Subresource Integrity. No restrictive Content Security Policy is present to constrain the loaded script. Consequently, the effective JavaScript payload can change after the Skill package has been reviewed. A compromise of the CDN, its account, DNS resolution, or the relevant upstream publication process could cause arbitrary JavaScript to execute in visitors' browsers. The generated build inlines the local theme and renderer scripts but leaves this external Tailwind runtime reference in place. Therefore, the output is not fully self-contained from a security or availability perspective. ### Attack Path 1. A user generates or initializes a travel page. 2. The page retains the external `https://cdn.tailwindcss.com` script reference. 3. The page is hosted or opened in a browser. 4. The browser requests the current JavaScript payload from the CDN. 5. If the external source or delivery path is compromised, the browser executes the substituted script. 6. The malicious script runs in the page's browser context and can inspect or alter page content and initiate network requests permitted by the browser. ### ...[truncated 702 chars]
Remediation
View remediation
` references. ]]>
Vulnerability Patterns
  • 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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (58)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill says it uses flyai/Fliggy plus metro data for broad planning, but some documented behavior only retrieves subway data from AMap and exports it via CLI. That is a narrower and different operational profile than the user-facing promise, which increases the chance of trust abuse and improper permissioning.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill says it uses flyai/Fliggy plus metro data for broad planning, but some documented behavior only retrieves subway data from AMap and exports it via CLI. That is a narrower and different operational profile than the user-facing promise, which increases the chance of trust abuse and improper permissioning.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill says it uses flyai/Fliggy plus metro data for broad planning, but some documented behavior only retrieves subway data from AMap and exports it via CLI. That is a narrower and different operational profile than the user-facing promise, which increases the chance of trust abuse and improper permissioning.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill says it uses flyai/Fliggy plus metro data for broad planning, but some documented behavior only retrieves subway data from AMap and exports it via CLI. That is a narrower and different operational profile than the user-facing promise, which increases the chance of trust abuse and improper permissioning.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill says it uses flyai/Fliggy plus metro data for broad planning, but some documented behavior only retrieves subway data from AMap and exports it via CLI. That is a narrower and different operational profile than the user-facing promise, which increases the chance of trust abuse and improper permissioning.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill says it uses flyai/Fliggy plus metro data for broad planning, but some documented behavior only retrieves subway data from AMap and exports it via CLI. That is a narrower and different operational profile than the user-facing promise, which increases the chance of trust abuse and improper permissioning.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill says it uses flyai/Fliggy plus metro data for broad planning, but some documented behavior only retrieves subway data from AMap and exports it via CLI. That is a narrower and different operational profile than the user-facing promise, which increases the chance of trust abuse and improper permissioning.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · SKILL.md (reported line 147)May include surrounding context.

md
- optional swap-ins
- niche / backup choices

## Output rules

- Always return a **curated plan**, not raw command output.
- If flyai returns image URLs, place the image line before the booking link.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill is described as a China travel planning capability, but this file implements local site building and GitHub Pages deployment, including repository mutation and publication. That mismatch increases risk because an agent invoking a travel-planning skill would not reasonably expect source-control manipulation or remote publishing side effects, enabling surprising file changes and data exposure.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code performs git branch switching, file deletion, commit creation, and remote push operations that are unjustified for a travel-planning skill. In agent contexts, unnecessary repository and publishing privileges materially expand attack surface and can lead to unauthorized code/content publication or destructive workspace changes if the skill is invoked unexpectedly.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The deploy flow performs branch checkout, repository-wide file removal, staging, commit, and push with no explicit confirmation or dry-run. In an agent setting this is highly dangerous because it combines destructive local changes with external publication, making accidental invocation capable of causing data loss and unauthorized release of content.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill documentation describes use of shell commands, network access, file reads, and file writes, but it does not declare any explicit tool scope or allowed-tools boundary. That creates an overprivileged and ambiguous execution model where an agent could invoke capabilities beyond what a travel-planning skill strictly needs, increasing the chance of unintended command execution or data handling.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger description is extremely broad and could cause the skill to activate for many generic travel requests, even when its advanced behaviors are unnecessary. Overbroad routing is dangerous in context because it increases the chances that users are exposed to hidden file/build/publish workflows when they expected simple travel advice.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation expands from travel assistance into a full page-generation pipeline that creates artifacts, validates them, builds a site, and prepares deployment. This is a scope increase into software/project automation, which creates additional risk around file writes, shell execution, and publishing that users would not reasonably infer from a travel-planner skill.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill documents GitHub Pages deployment even though public publishing is not justified by the core travel-planning purpose. A deployment step can expose itinerary details, personal travel dates, hotel choices, or other sensitive trip data to the public if triggered without strong safeguards.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The deployment instructions omit any warning that generated travel pages may publish personal or sensitive itinerary information. In a travel context, dates, cities, hotels, and movement plans can create privacy and safety risks if exposed publicly without informed consent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The document sets lang="zh-CN" and the visible interface text throughout the page is in Chinese, which imposes a specific language/locale on users. The file does not provide any opt-in, language selector, or documentation indicating that this is intentionally limited to a China-specific audience.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Line L042 instructs authors to keep the summary under 90 Chinese characters when possible, which imposes a specific language/locale expectation in natural language. The file does not indicate that Chinese output is optional, user-selected, or required for a clearly documented region-specific purpose.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The module usage text and cmd_validate docstring say the tool validates trip-data.json against a schema, and a schema path is defined. In practice, the code never reads or applies the schema file; it only checks JSON syntax plus a few required keys and list types, which contradicts the documented intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The build command unconditionally deletes and recreates the dist directory, which can destroy user data or overwrite expected artifacts without a warning or confirmation step. In an agent-executed context, non-interactive destructive file operations are dangerous because users may not realize a travel-related action can modify local project contents.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · page-generator/scripts/tpf-cli.py (reported line 168)May include surrounding context.

python
error("Not a git repository. Run: git init")

    # Check remote
    result = subprocess.run(
        ["git", "remote", "-v"],
        cwd=project_dir,
        capture_output=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · page-generator/scripts/tpf-cli.py (reported line 192)May include surrounding context.

python
try:
        # Check if gh-pages branch exists
        result = subprocess.run(
            ["git", "branch", "--list", "gh-pages"],
            cwd=project_dir,
            capture_output=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · page-generator/scripts/tpf-cli.py (reported line 201)May include surrounding context.

python
if "gh-pages" not in result.stdout:
            # Create orphan branch
            subprocess.run(
                ["git", "checkout", "--orphan", "gh-pages"],
                cwd=project_dir,
                check=True

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · page-generator/scripts/tpf-cli.py (reported line 206)May include surrounding context.

python
cwd=project_dir,
                check=True
            )
            subprocess.run(
                ["git", "rm", "-rf", "."],
                cwd=project_dir,
                check=True

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · page-generator/scripts/tpf-cli.py (reported line 212)May include surrounding context.

python
check=True
            )
        else:
            subprocess.run(
                ["git", "checkout", "gh-pages"],
                cwd=project_dir,
                check=True