T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:32
- Finding
- Shell Command Injection Through Unsafe User-Question Substitution<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 32-41; equivalent vulnerable patterns also appear at lines 46-55 and 60-70 **Vulnerability Type**: Shell command injection and improper JSON construction **Risk Level**: High ### Vulnerable Code ```bash curl -s -X POST https://quorumai.io/api/v1/inquiry \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $QUORUMAI_API_KEY" \ -d '{ "thesis": "USER_QUESTION_HERE", "mode": "quick", "academy": "general" }' ``` The instruction at line 145 requires direct substitution: ```markdown - Always substitute the user's actual question for `USER_QUESTION_HERE` ``` The same unsafe substitution pattern is used by the Standard and Deep Inquiry command examples. ### Technical Analysis The skill instructs the agent to replace `USER_QUESTION_HERE` with untrusted user input inside a single-quoted shell argument. It does not require JSON serialization, shell escaping, or passing the question through a separate data channel. A question containing a single quote can terminate the shell argument. Subsequent shell metacharacters may then be interpreted as commands by the local shell. Even when command execution is not achieved, quotation marks, backslashes, control characters, or newlines in the question can corrupt the JSON document and alter or invalidate the API request. The vulnerability is exploitable when an implementing agent performs literal substitution in the documented command and executes the result through a shell. ### Attack Path 1. An attacker asks the agent to use QuorumAI with a question containing a single quote followed by shell operators and an attacker-selected command. 2. The agent follows `SKILL.md` and directly replaces `USER_QUESTION_HERE` with the supplied text. 3. The injected single quote closes the `curl -d` shell argument prematurely. 4. The shell parses the remaining attacker-controlled text as shell syntax. 5. The injected command executes lo ...[truncated 763 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Do not interpolate user-controlled content into shell source. Build the request body with a JSON-aware serializer and pass it to `curl` as a separately quoted value: ```bash payload=$(jq -n \ --arg thesis "$USER_QUESTION" \ '{thesis: $thesis, mode: "quick", academy: "general"}') curl -sS -X POST https://quorumai.io/api/v1/inquiry \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $QUORUMAI_API_KEY" \ --data-binary "$payload" ``` Apply the same correction to the Quick, Standard, and Deep Inquiry examples. Define `USER_QUESTION` as data supplied through a structured tool parameter or environment/input channel rather than generating shell text through placeholder replacement. Prefer a structured HTTP client that accepts the URL, headers, and JSON body as distinct arguments without invoking a shell. Additional hardening should include: - Validate the selected `mode`, `academy`, and `arbiter` against fixed allowlists. - Avoid logging the authorization header or full process environment. - Run the integration with minimal filesystem and network permissions. - Ensure errors and debug output cannot disclose `QUORUMAI_API_KEY`. - Add tests using questions containing single quotes, double quotes, backslashes, newlines, Unicode, and shell metacharacters. ]]>
