T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:118
- Finding
- Shell Command Injection Through User-Controlled CSV Content<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 118–132 **Vulnerability Type**: Shell command injection **Risk Level**: High ### Vulnerable Code ```markdown When the user provides a travel plan, convert it into CSV format and invoke the API: > User: Help me plan a two-day trip. > Assistant: (After checking `CYEAM_API_KEY`, convert the plan into CSV and invoke the API.) curl -X POST "https://cyeam-open-main-d02895c.d2.zuplo.dev/api/roadbook/csv" \ -H "Authorization: Bearer $CYEAM_API_KEY" \ -H "Content-Type: text/plain" \ -d "Hotel,Hotel Street,Accommodation,Day1,Check-in Morning Market,Market Street,Dining,Day2,Breakfast Ceramics Museum,Museum Road,Attraction,Day2,Afternoon visit Barbecue Restaurant,Restaurant Street,Dining,Day2,Dinner" > Assistant: The roadbook has been generated. ``` ### Technical Analysis The Skill instructs the agent to transform arbitrary user-supplied itinerary fields into CSV and place the resulting content directly inside a double-quoted shell argument passed to `curl -d`. Double quotes do not disable all shell interpretation. Command substitutions using `$(...)` or backticks are evaluated inside double-quoted strings before `curl` executes. Embedded quotation marks can also terminate the intended argument and alter the command structure. For example, if a user supplies an itinerary note containing `$(malicious_command)`, and the agent copies it into the documented command template, the shell may execute `malicious_command` locally rather than treating it solely as CSV data. The issue arises because data and shell syntax are combined in a generated command string without a non-shell data boundary. Exploitation is conditional on the agent executing the generated command through a shell, but that is the exact invocation pattern documented by the Skill. ### Attack Path 1. An attacker supplies a travel plan containing shell syntax in a CSV field such as a place name, address, or note. 2. The agent ...[truncated 1176 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not construct or execute shell command strings containing user-derived CSV data. 2. Prefer a structured HTTP client or tool API that accepts the URL, headers, and request body as separate values without invoking a shell. 3. If `curl` must be used, pass the request body over standard input and invoke the executable through an argument-array API: ```text CSV bytes → process standard input Arguments → ["curl", "--fail-with-body", "--data-binary", "@-", ...] Shell → disabled ``` 4. Explicitly state in the Skill that generated CSV must never be interpolated into shell source, including double-quoted shell arguments. 5. Keep the API key in a dedicated authorization-header argument and prevent it from appearing in logs, diagnostics, or generated command text. 6. Validate CSV structure separately for correctness, including the required five-column limit and proper CSV quoting. Validation should be defense in depth and must not replace elimination of shell interpretation. 7. Apply least privilege to the agent runtime, restrict filesystem and outbound-network access, and ensure the API key has only the permissions required to create roadbooks. ]]>
