T09 · Insecure Skill Coding Practices
- Location
SKILL.md:69- Finding
Shell Command Injection Through Unescaped Dynamic Data
- Content
View full analysis
' > /tmp/holdings_update.json curl -sS -X POST http://localhost:8000/api/holdings/bulk \ -H "Content-Type: application/json" \ -d "{\"holdings\": $(cat /tmp/holdings_update.json), \"label\": \" screenshot import\"}" rm /tmp/holdings_update.json ``` The same unsafe construction pattern is used for diary data: ```bash curl -sS -X POST http://localhost:8000/api/diary \ -H "Content-Type: application/json" \ -d "{\"date\": \"\", \"type\": \"\", \"code\": \"\", \"remark\": \"\", \"mood\": \"\"}" ``` ### Technical Analysis The instructions direct the agent to insert AI-generated analysis results and user-provided values directly into shell commands. These values cross two independent parsing boundaries: 1. The shell parses quoting, command substitution, redirection, and metacharacters. 2. The server subsequently parses the resulting text as JSON. JSON escaping does not make a value safe for interpolation into a shell command. In particular: - A single quote in the analyzed holdings data can terminate the quoted `echo` argument. - Double quotes, backticks, `$()`, semicolons, redirection operators, or newline characters in dynamically substituted values can change the command structure. - Diary remarks, labels, stock names, screenshot-derived values, and supplemental notes may originate from untrusted users or AI recognition output. - AI output must not be treated as trusted merely because it is expected to be JSON. The documented confirmation step does not prevent exploitation because users may confirm a legitimate-looking preview without seeing the shell rep ...[truncated 1296 chars]- Remediation
View remediation
'` to serialize untrusted content. 6. Validate the complete data schema before submission, including types, lengths, numeric ranges, stock-code formats, and permitted diary values. 7. Treat screenshot-recognition output as untrusted input. 8. Present the exact structured request body for confirmation rather than a simplified rendering. ]]>
