T09 · Insecure Skill Coding Practices
- 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
