Back to skill

Security audit

Umy Hotel

Security checks for vulnerabilities and agentic risk

Overview

The skill performs hotel search, but its docs understate the executable code and how travel data and booking links are handled.

Review this before installing. It is not clearly malicious, but users should understand that hotel searches can send precise location, dates, hotel IDs, and query text to Umy, and that the included script adds Umy booking links to results. Avoid entering personal information in hotel queries, and prefer a dedicated API key if you need reliable quota or attribution.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/umy_hotel_tool.mjs:45
Finding

Unvalidated Free-Form Query and Precise Travel Data Transmitted to an External Service

Content
View full analysis
controller.abort(), timeoutMs); try { const response = await fetch(`${API_BASE}/hotel/search`, { method: "POST", headers: { "X-API-Key": API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ location: params.location, check_in_date: params.checkIn, check_out_date: params.checkOut, query: params.query || "", radius: parseFloat(params.radius) || 5, currency: params.currency || "CNY" }), signal: controller.signal, }); if (!response.ok) { const text = await response.text(); throw new Error(`HTTP ${response.status}: ${text}`); } return await response.json(); } finally { clearTimeout(timeout); } } ``` The user-controlled query is assigned without filtering: ```javascript } else if (args[i] === "--query" && args[i + 1]) { params.query = args[++i]; } ``` ### Technical Analysis The CLI accepts arbitrary values for `--query` and `--location` and sends them to `https://api.umy.com/v1/hotel/search`. There is no runtime schema validation, personal-information detection, allowlist enforcement, or sanitization before the request is made. This conflicts with the policy in `SKILL.md`, which states that the query must contain only a hotel name and that personally identifiable information must be removed. The prompt files instruct the agent to perform that filtering, but relying exclusively on instruction-following is not a security boundary. The executable ...[truncated 1751 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/umy_hotel_tool.mjs:13
Finding

Reusable Shared API Credential Embedded in Documentation and Executable Code

Content
View full analysis
Remediation
View remediation

other

Warning
Location
scripts/umy_hotel_tool.mjs:98
Finding

Automatic Injection of Undisclosed Umy Booking Links into Search Results

Content
View full analysis
{ const processed = addBookingLink(hotel); // Also add booking links to nested structures if present if (processed.price) { processed.price.booking_url = processed.booking_url; processed.price.booking_link = processed.booking_link; } return processed; }); } ``` The modification is automatically applied to search results: ```javascript // Add booking links to all hotels if (result.hotels) { result.hotels = processHotels(result.hotels); } ``` It is also applied to hotel-detail responses: ```javascript // Add booking link if (result.hotel) { result.hotel = addBookingLink(result.hotel); } ``` ### Technical Analysis The tool rewrites every returned hotel object to add two Umy links and additionally inserts those links into nested price objects. This happens automatically and is not necessary to conduct a hotel search or display the original API response. The declared Skill description presents the package as a hotel-search capability but does not clearly disclose that local executable code modifies results to add promotional or provider-specific navigation links. This can cause downstream agents and users to treat locally injected links as neutral fields supplied by the search source. The code does not establish that the URLs contain affiliate identifiers, so no affiliate relationship should be inferred. The confirmed issue is undisclosed provider-spe ...[truncated 1147 chars]
Remediation
View remediation

other

Warning
Location
SKILL.md:50
Finding

Security Documentation Incorrectly Claims the Package Contains No Executable Code

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The trigger conditions are broad enough that ordinary travel discussion or recommendation requests could cause the agent to invoke the hotel search tool without clear user intent to perform an external action. In a tool-using agent, this can lead to unnecessary data transmission and privacy-impacting overcollection, especially when paired with required extraction of dates and location coordinates.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The prompt explicitly instructs the agent to resolve user-described places and look up coordinates, but provides no requirement to disclose that an external lookup may occur or that location data may be sent to a third party. In a hotel-search skill, location and travel dates are sensitive enough that silent enrichment increases privacy risk and can surprise users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

整个技能以中文固定描述输入解析与行为规则,未说明这是面向特定中文场景的限定配置,也未提供用户语言选择或显式 opt-in。按组织语言/locale 政策,这可能构成默认强制特定语言的自然语言策略问题。

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger conditions are very broad, covering generic requests like wanting hotels, mentioning a place plus lodging needs, or asking for recommendations. Overbroad triggers can cause unintended tool invocation on ambiguous user input, sending extracted travel intent, dates, and location-derived coordinates to an external service without sufficiently clear user intent.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/umy_hotel_tool.mjs (reported line 13)May include surrounding context.

js
*   node scripts/umy_hotel_tool.mjs detail --hotel-id 15084192
 */

const API_BASE = "https://api.umy.com/v1";
const API_KEY = process.env.UMY_API_KEY || "umyf1a1e67eae96d612c0d5a09e2d9cdf4f";

function showHelp() {

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script embeds a usable fallback API key directly in source code, which exposes the credential to anyone who can read the file and enables unauthorized use of the Umy API. In a distributed skill or public repository, this can lead to key theft, quota exhaustion, billing abuse, and makes secret rotation harder because the credential is baked into the artifact.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code performs a network POST to a third-party service and includes potentially sensitive travel data such as location, check-in date, check-out date, and query terms. While the header comment says it connects to the Umy MCP server, there is no runtime disclosure, prompt, or explicit warning to the user that their inputs are transmitted externally.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The prompt defines query as the optional hotel-name keyword field and gives detailed requirements for how it should be populated, but the example call uses originQuery instead. This actively conflicts with the documented interface and could cause the agent to supply the wrong argument to the hotel search tool.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The arguments table says currency defaults to CNY at L26, but the later usage instructions say the default should be USD at L63. This is an active contradiction within the skill's own documentation and can cause the agent to invoke the hotel search tool with different semantics than documented.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The prompt defines the optional hotel keyword field as query and explains how it must be sanitized and populated, but the final JSON example uses originQuery instead. This directly conflicts with the documented interface and can cause the agent to call the tool with an undocumented argument.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This function makes an HTTP POST to an external endpoint using user-supplied input, but the script provides no explicit user-facing warning at execution time or in help output that requests are sent to a remote service. The operation is networked and should be disclosed even if it is central to the tool's purpose.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/umy_hotel_tool.mjs:14