Back to skill

Security audit

Travelmapify

Security checks for vulnerabilities and agentic risk

Overview

This travel-map skill has a coherent purpose, but it should be reviewed because its local helper services can execute unsafe commands and expose more workspace data than needed.

Do not install this version without review or fixes. Require the publisher to replace shell exec with argument-array execution, bind local services to loopback with restricted CORS/auth where needed, serve only a dedicated output directory, stop killing unknown port owners, remove or rotate the shared Amap key, pin dependencies, and sanitize generated HTML and localStorage-rendered data.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (6)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/amap-proxy.js:9
Finding
Unauthenticated Shell Command Injection in the Amap Proxy<![CDATA[ ## Vulnerability Details **File Location**: `scripts/amap-proxy.js`, lines 9–25, 45–53, and 74–101 **Vulnerability Type**: OS command injection through unauthenticated HTTP parameters **Risk Level**: Critical ### Vulnerable Code ```javascript // CORS headers const corsHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept' }; // Handle search requests function handleSearch(query, city, response) { // Use relative path to amap-maps skill const amapMapsDir = path.join(__dirname, '..', '..', 'amap-maps'); // Use default API key or allow override via environment variable const amapKey = process.env.AMAP_KEY || "88628414733cf2ccb7ce2f94cfd680ef"; const command = `cd "${amapMapsDir}" && AMAP_KEY="${amapKey}" node scripts/amap.js search text "${query}" ${city}`; exec(command, { timeout: 10000 }, (error, stdout, stderr) => { if (error) { console.error('Search error:', error); response.writeHead(500, corsHeaders); response.end(JSON.stringify({ error: 'Search failed', details: error.message })); return; } // ... }); } function handleDetail(poiId, response) { const amapMapsDir = path.join(__dirname, '..', '..', 'amap-maps'); const amapKey = process.env.AMAP_KEY || "88628414733cf2ccb7ce2f94cfd680ef"; const command = `cd "${amapMapsDir}" && AMAP_KEY="${amapKey}" node scripts/amap.js search detail "${poiId}"`; exec(command, { timeout: 10000 }, (error, stdout, stderr) => { // ... }); } ``` The affected values originate from HTTP requests: ```javascript if (pathname === '/api/search' && req.method === 'GET') { const query = parsedUrl.query.q; const city = parsedUrl.query.city || '重庆'; // ... handleSearch(query, city, res); } if (pathname.startsWith('/api/detail ...[truncated 1974 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace `exec()` with `execFile()` or `spawn()` and pass every argument as a separate array element: ```javascript const { execFile } = require('child_process'); execFile( 'node', [ path.join(amapMapsDir, 'scripts', 'amap.js'), 'search', 'text', query, city ], { cwd: amapMapsDir, env: { ...process.env, AMAP_KEY: amapKey }, timeout: 10000 }, callback ); ``` 2. Validate request parameters before execution: - Enforce length limits. - Reject control characters. - Restrict city and POI identifiers to expected character sets and formats. 3. Bind the service explicitly to `127.0.0.1`. 4. Replace wildcard CORS with an explicit allowlist of trusted origins. 5. Add request authentication if the proxy can ever be exposed beyond loopback. 6. Apply request-rate limits and return generic errors without command details. 7. Never interpolate environment values into shell command strings. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/main_travel_mapify_enhanced.py:87
Finding
OpenClaw Workspace Exposed Through a Broad HTTP Document Root<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main_travel_mapify_enhanced.py`, lines 87–94 **Vulnerability Type**: Excessive file exposure and insecure server binding **Risk Level**: High ### Vulnerable Code ```python # Start HTTP server in background cmd = [sys.executable, "-m", "http.server", str(current_port)] http_process = subprocess.Popen( cmd, cwd=WORKSPACE_DIR, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, preexec_fn=os.setpgrp # Create new process group ) ``` The document root comes from `scripts/config.py`: ```python # Configuration constants WORKSPACE_DIR = get_workspace_dir() SKILL_DIR = get_skill_dir() FLYAI_EXECUTABLE = find_flyai_executable() ``` ### Technical Analysis The generated map only requires a narrow output directory to be served. Instead, the code starts Python’s generic `http.server` with `cwd=WORKSPACE_DIR`, making the entire detected OpenClaw workspace the web document root. Python’s default HTTP server permits retrieval of readable files beneath that directory and generally provides directory listings when no index file is present. The command also does not pass `--bind 127.0.0.1`, so the service may listen on all interfaces rather than only loopback. The workspace may contain Agent configuration, other skills, generated artifacts, or user files unrelated to the map. ### Attack Path 1. A user generates a travel map. 2. The Skill starts `python -m http.server` in the OpenClaw workspace. 3. The service listens on the selected port and exposes the workspace as its document root. 4. A host that can connect to that port requests `/` or guesses workspace-relative paths. 5. Directory listings reveal available files, which the requester downloads over HTTP. ### Impact Assessment An attacker may obtain any workspace file readable by the Skill account and reachable below the document root. Depending on workspace contents, this may disclose: - Agent configuration and behavioral files. - ...[truncated 356 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a dedicated output directory containing only generated map assets. 2. Start the server with that directory as the document root rather than `WORKSPACE_DIR`. 3. Bind explicitly to loopback: ```python cmd = [ sys.executable, "-m", "http.server", str(current_port), "--bind", "127.0.0.1", "--directory", dedicated_output_dir, ] ``` 4. Prefer a custom request handler that disables directory listings and serves only explicitly authorized files. 5. Reject path traversal and symbolic-link escape from the output directory. 6. Stop the server when the operation or user session ends. 7. If remote sharing is required, add authentication, TLS, and an explicit access-control policy. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_from_optimized_template.py:37
Finding
Stored and DOM-Based Script Injection in Generated Travel Maps<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_from_optimized_template.py`, lines 37–63 **Additional Sinks**: `assets/templates/main-generic-template-with-unique-id.html`, lines 479–490, 527–554, 751–767, 852–877, and 927–957 **Vulnerability Type**: Unsafe JavaScript generation and DOM XSS **Risk Level**: High ### Vulnerable Code The generator inserts unescaped values into JavaScript source: ```python def generate_poi_js_array(pois): """Generate JavaScript POI array from POI list""" js_lines = [] for poi in pois: name = poi.get('name', 'Unnamed Location') address = poi.get('address', '') rating = poi.get('rating', '') poi_id = poi.get('id', '') # Handle location coordinates if isinstance(poi.get('location'), list) and len(poi['location']) == 2: lng, lat = poi['location'][0], poi['location'][1] else: lng, lat = 116.4074, 39.9042 js_lines.append(' {') js_lines.append(f' name: "{name}",') js_lines.append(f' location: [{lng}, {lat}],') js_lines.append(f' address: "{address}",') js_lines.append(f' rating: "{rating}",') js_lines.append(f' id: "{poi_id}"') js_lines.append(' },') ``` The template later places these values into HTML strings: ```javascript var infoContent = `<div style="padding:14px; min-width:220px; background:white;"> <h4>${number}. ${poi.name}</h4> <p>${poi.address || ''}</p>`; ``` ```javascript html += ` <div class="poi-item" draggable="true" data-index="${index}"> <div class="poi-number">${index + 1}</div> <div class="poi-name">${poi.name}</div> <div class="poi-actions"> <button class="remove-btn" onclick="removePOI(${index})">×</button> </div> </div> `; poiListDiv.innerHTML = html; ``` Search ...[truncated 2827 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Serialize the full POI structure with `json.dumps()` rather than constructing JavaScript source manually: ```python poi_json = json.dumps(pois, ensure_ascii=False) template_content = template_content.replace( '/* POI_DATA_PLACEHOLDER */', poi_json ) ``` 2. Ensure embedded JSON cannot terminate the script element, for example by escaping `<` or replacing `</script`. 3. Replace `innerHTML` with DOM construction and assign all untrusted text through `textContent`. 4. Replace inline `onclick` attributes with `addEventListener`. 5. Validate longitude and latitude as finite numbers within valid geographic ranges. 6. Allowlist URL schemes and preferably require `https:` for `mainPic` and `detailUrl`. 7. Add `rel="noopener noreferrer"` to links opened with `target="_blank"`. 8. Validate data loaded from `localStorage` against a strict schema before rendering. 9. Add a restrictive Content Security Policy that disallows inline scripts and event handlers. 10. Treat all Amap and FlyAI response values as untrusted external input. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/ensure_servers_running.py:24
Finding
Automatic Termination of Unrelated Processes Occupying Fixed Ports<![CDATA[ ## Vulnerability Details **File Location**: `scripts/ensure_servers_running.py`, lines 24–38, 43–46, and 79–82 **Vulnerability Type**: Unsafe process management and denial of service **Risk Level**: Medium ### Vulnerable Code ```python def kill_process_on_port(port): """Force kill any process running on the specified port""" try: # Find process using the port result = subprocess.run(['lsof', '-ti', f':{port}'], capture_output=True, text=True) if result.returncode == 0 and result.stdout.strip(): pid = result.stdout.strip() print(f"Killing existing process on port {port} (PID: {pid})") os.kill(int(pid), signal.SIGTERM) time.sleep(1) # Force kill if still running if is_port_in_use(port): os.kill(int(pid), signal.SIGKILL) time.sleep(1) except Exception as e: print(f"Warning: Could not kill process on port {port}: {e}") ``` The function is called before starting both services: ```python # Kill any existing process on port 8769 kill_process_on_port(AMAP_PROXY_PORT) ``` ```python # Kill any existing process on port 8780 kill_process_on_port(HOTEL_SERVER_PORT) ``` ### Technical Analysis The code assumes that any process bound to ports 8769 or 8780 can be safely terminated. It does not verify: - The executable or command line of the process. - Whether the process belongs to this Skill. - Whether it was launched during the current session. - Whether the service is healthy and compatible. - Whether the PID changed between discovery and termination. After sending `SIGTERM`, the code may send `SIGKILL`, preventing the target from performing graceful cleanup. There is also a time-of-check/time-of-use concern because the PID and port ownership can change. This behavior contradicts the safer documented objective of avoiding conflicts. ### Attack Path 1. A legitimate application is listening on port 8769 or 8780 ...[truncated 855 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Never terminate an unknown process solely because it occupies a desired port. 2. Query an existing service through a unique health endpoint and reuse it only if its identity and protocol match expectations. 3. If the port is unavailable, choose an unused alternative port or fail with a clear error. 4. Track PIDs only for processes launched by the current Skill instance. 5. Before terminating a tracked PID, verify its process start time and command line to prevent PID-reuse errors. 6. Prefer graceful shutdown and provide adequate cleanup time. 7. Reserve `SIGKILL` for explicit administrative intervention rather than routine startup. 8. Propagate the dynamically selected port consistently into generated HTML and server configuration. ]]>

T08 · Insecure Dependencies

Warning
Location
INSTALL.md:72
Finding
Unpinned Global Installation of an Executed Third-Party Package<![CDATA[ ## Vulnerability Details **File Location**: `INSTALL.md`, line 72 **Additional Locations**: `SKILL.md`, line 190; `DEPLOYMENT.md`, line 87 **Vulnerability Type**: Unpinned global dependency installation **Risk Level**: Medium ### Vulnerable Code ```bash npm install -g @openclaw/flyai ``` The resulting executable is subsequently discovered and invoked by the Skill. For example, `scripts/hotel-search-server.py` constructs and runs the FlyAI command: ```python cmd = [ flyai_cmd, 'search-hotel', '--dest-name', destination, '--check-in-date', checkin, '--check-out-date', checkout ] if poi_name: cmd.extend(['--poi-name', poi_name]) result = subprocess.run(cmd, capture_output=True, text=True, timeout=30) ``` ### Technical Analysis The installation command does not pin an exact version and does not document integrity verification. It therefore installs whichever version the configured npm registry resolves at installation time. Because npm package installation can execute lifecycle scripts and because the resulting FlyAI executable is later run directly, compromise of the package, registry resolution, maintainer account, or a future release can result in local code execution. Global installation also expands the package’s effect beyond an isolated project environment. No evidence in the reviewed project demonstrates that the package is malicious. The vulnerability is the unsafe dependency acquisition and execution model. ### Attack Path 1. A user follows the documented installation command. 2. npm resolves the current release of `@openclaw/flyai` from the configured registry. 3. A compromised or unexpectedly changed package version is installed globally. 4. Package lifecycle code may execute during installation. 5. The Skill later discovers and runs the globally installed `flyai` executable. 6. Malicious package code executes with the user’s privileges. ### Impact Assessment A compromised dependency could: - Execute arbitra ...[truncated 403 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin an audited exact package version: ```bash npm install --save-exact @openclaw/flyai@X.Y.Z ``` 2. Prefer a project-local installation over `-g`. 3. Commit and enforce a lockfile with integrity metadata. 4. Use `npm ci` in controlled deployments. 5. Document the expected npm registry and prevent dependency resolution from untrusted registries. 6. Verify package provenance, signatures, checksums, and maintainer identity where supported. 7. Review lifecycle scripts before installation and consider disabling them when they are unnecessary. 8. Run the FlyAI executable with restricted filesystem and network permissions. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/amap-proxy.js:21
Finding
Hardcoded and Publicly Distributed Amap API Credential<![CDATA[ ## Vulnerability Details **File Location**: `scripts/amap-proxy.js`, lines 21–22 and 49–50 **Additional Location**: `assets/templates/main-generic-template-with-unique-id.html`, line 368 **Vulnerability Type**: Hardcoded API credential exposure **Risk Level**: Medium ### Vulnerable Code The proxy embeds a default API key: ```javascript // Use default API key or allow override via environment variable const amapKey = process.env.AMAP_KEY || "88628414733cf2ccb7ce2f94cfd680ef"; ``` The same value is shipped in browser-visible template source: ```html <script src="https://webapi.amap.com/maps?v=2.0&key=88628414733cf2ccb7ce2f94cfd680ef"></script> ``` ### Technical Analysis The API key is committed to source code and included in generated client-side HTML. Any person who can obtain the project or generated page can copy and reuse it. An environment-variable override does not protect the embedded fallback. Browser-side API keys may sometimes be intentionally public, but they still require strict provider-side origin, service, quota, and usage restrictions. The project provides no evidence in the reviewed code that such restrictions are enforced. The same key is used in both browser and proxy contexts, broadening its exposure and making rotation more difficult. ### Attack Path 1. An attacker downloads the repository, receives a generated map, or inspects the page source. 2. The attacker extracts the Amap key from the script URL or proxy source. 3. The attacker uses the key in unauthorized API requests. 4. Requests consume the project’s quota or trigger provider abuse controls. 5. The legitimate application experiences throttling, billing impact, or key revocation. ### Impact Assessment Potential consequences include: - Unauthorized use of the project’s Amap quota. - Service degradation or denial of service through quota exhaustion. - Unexpected charges where usage is billable. - Key suspension or revocation by the provider. - Difficulty attribu ...[truncated 205 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the hardcoded key from the repository and rotate the exposed value. 2. Require server-side configuration through a protected environment variable or secret manager. 3. Do not reuse the same credential for browser and server operations. 4. For browser-required keys, create a separate restricted key and enforce: - Exact origin allowlists. - API/service allowlists. - Conservative quotas and rate limits. - Usage monitoring and automated abuse alerts. 5. Prevent privileged server-side keys from appearing in generated HTML. 6. Add secret-scanning checks to source-control and release pipelines. 7. Document secure setup rather than advertising a built-in shared key. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (63)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Claiming implemented map creation, hotel search, and AI Vision while returning placeholders is deceptive from a security perspective because it undermines trust in the skill manifest. In a plugin ecosystem, inaccurate manifests can be abused to smuggle in unrelated privileged behavior behind an appealing description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
Claiming implemented map creation, hotel search, and AI Vision while returning placeholders is deceptive from a security perspective because it undermines trust in the skill manifest. In a plugin ecosystem, inaccurate manifests can be abused to smuggle in unrelated privileged behavior behind an appealing description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Claiming implemented map creation, hotel search, and AI Vision while returning placeholders is deceptive from a security perspective because it undermines trust in the skill manifest. In a plugin ecosystem, inaccurate manifests can be abused to smuggle in unrelated privileged behavior behind an appealing description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
Claiming implemented map creation, hotel search, and AI Vision while returning placeholders is deceptive from a security perspective because it undermines trust in the skill manifest. In a plugin ecosystem, inaccurate manifests can be abused to smuggle in unrelated privileged behavior behind an appealing description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
Claiming implemented map creation, hotel search, and AI Vision while returning placeholders is deceptive from a security perspective because it undermines trust in the skill manifest. In a plugin ecosystem, inaccurate manifests can be abused to smuggle in unrelated privileged behavior behind an appealing description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
Claiming implemented map creation, hotel search, and AI Vision while returning placeholders is deceptive from a security perspective because it undermines trust in the skill manifest. In a plugin ecosystem, inaccurate manifests can be abused to smuggle in unrelated privileged behavior behind an appealing description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Claiming implemented map creation, hotel search, and AI Vision while returning placeholders is deceptive from a security perspective because it undermines trust in the skill manifest. In a plugin ecosystem, inaccurate manifests can be abused to smuggle in unrelated privileged behavior behind an appealing description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
Claiming implemented map creation, hotel search, and AI Vision while returning placeholders is deceptive from a security perspective because it undermines trust in the skill manifest. In a plugin ecosystem, inaccurate manifests can be abused to smuggle in unrelated privileged behavior behind an appealing description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
Claiming implemented map creation, hotel search, and AI Vision while returning placeholders is deceptive from a security perspective because it undermines trust in the skill manifest. In a plugin ecosystem, inaccurate manifests can be abused to smuggle in unrelated privileged behavior behind an appealing description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
Claiming implemented map creation, hotel search, and AI Vision while returning placeholders is deceptive from a security perspective because it undermines trust in the skill manifest. In a plugin ecosystem, inaccurate manifests can be abused to smuggle in unrelated privileged behavior behind an appealing description.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The code builds a shell command with untrusted user-controlled values (`query` and `city`) and executes it via `child_process.exec`. Because these values are interpolated directly into a shell string without escaping, an attacker can inject shell metacharacters and execute arbitrary commands on the host running the skill.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
The file describes city detection using Chinese place names and states a default fallback to Shanghai, but nowhere indicates that the skill is China-specific or that users can choose another language/locale. Under the policy, forcing a specific language or locale without opt-in is a natural-language policy concern.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
Stating that a built-in default Amap API key is included and that no user key is required suggests the skill may embed shared credentials. Embedded default API keys can be extracted, abused by unauthorized parties, tied to the developer's account, and may expose users to undisclosed data-sharing and privacy risks when location queries are sent through that credential.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The requirements document discloses a built-in Amap API key and explicitly encourages using it by stating that no user key is required. Hardcoded shared API keys are sensitive operational secrets: they can be copied by anyone with access to the repository, abused outside the intended skill, and lead to quota exhaustion, billing exposure, or service suspension for all users of the skill. In this skill context, the issue is more dangerous because the key is presented as the default operational path, which promotes widespread reuse of the same credential.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill advertises and appears to require broad capabilities including shell execution, file I/O, environment access, and network access, yet it declares no explicit tool/permission scope. That makes review, sandboxing, and least-privilege enforcement much harder, and increases the chance an agent grants more access than users expect.

Session Persistence

Medium
Category
Rogue Agent
Content
---
name: flyai-travelmapify
version: 2.2.2
description: Create interactive travel route maps from location names with real FlyAI hotel search. Supports AI Vision analysis of travel planning images.
author: rudy2steiner
license: MIT
tags: [travel, maps, routing, geocoding, flyai, hotels, unique-id, server-management, interactive, ai-vision]
Confidence
73% confidence
Finding
The skill emphasizes unique-ID and persistent per-map localStorage state, which creates session persistence of user itinerary, hotel search preferences, and related travel data in the browser. In a travel context this can expose sensitive movement/planning information to other users of the same browser profile or to other scripts if the application is not carefully isolated.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
Automatically starting local HTTP services without a prominent user warning is risky because it silently changes the system's network exposure and process state. Even when bound locally, this can create conflict with existing services, expose sensitive data, or be reachable by other local users/processes.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The documentation is internally inconsistent about whether image analysis is performed by the skill or externally by the agent's AI Vision. That ambiguity matters because it obscures which component accesses user images and where responsibility, permissions, and data handling actually lie.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The visible UI text is entirely in Chinese, and the map is explicitly configured with `lang: 'zh_cn'`, which enforces a specific locale. There is no user opt-in, language selector, or documentation indicating that this is an intentionally region-specific tool.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
User-entered search queries are sent to a localhost HTTP service without informing the user. Even though the destination is local, localhost services can bridge to privileged local components, and the plaintext HTTP channel plus lack of disclosure makes the data flow unexpected and privacy-relevant.

Description-Behavior Mismatch

Medium
Confidence
90% confidence
Finding
The template persists POI itinerary data and travel dates in localStorage, which creates durable client-side storage of potentially sensitive travel history. In a skill context, this exceeds transient rendering needs and can expose private trip details to other scripts running in the same origin or to later users of the same browser profile/shared device.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The code stores itinerary and travel dates without any visible notice, consent, or retention explanation. Travel plans can reveal future absence, location patterns, and personal habits, so silent persistence creates a privacy risk even if no immediate exfiltration is shown.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The hotel search request transmits destination, POI, and travel dates to a backend service without any user-facing privacy notice. These fields are sensitive because they can reveal intended travel, timing, and interests, and in this skill they are sent automatically as part of a convenience action.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
try:
        # Execute the main script
        result = subprocess.run(cmd)
        sys.exit(result.returncode)
    except KeyboardInterrupt:
        print("\nOperation cancelled by user", file=sys.stderr)
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The example sets `lang: 'zh_cn'`, which forces a specific language/locale in the map UI. Under the stated policy, locale-specific behavior should either be user-selectable or clearly documented as a justified regional constraint.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/amap-proxy.js:25