T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:27
- Finding
- Shell Command Injection Through Unsafe User Request Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:27-30` **Vulnerability Type**: Shell command injection caused by unsafe interpolation of user-controlled input **Risk Level**: High ### Vulnerable Code ```bash curl -s -X POST "$HASS_SERVER/api/conversation/process" \ -H "Authorization: Bearer $HASS_TOKEN" \ -H "Content-Type: application/json" \ -d '{"text": "USER REQUEST HERE", "language": "en"}' ``` ### Technical Analysis The skill instructs the agent to place the user's natural-language request directly into a single-quoted shell argument. It does not require a JSON-aware serializer or define a safe mechanism for passing the request to the command. If `USER REQUEST HERE` is replaced through direct textual substitution, an input containing a single quote can terminate the shell argument. The remaining input can then introduce shell operators and arbitrary commands. Escaping for JSON alone is insufficient because shell quoting and JSON encoding are separate security boundaries. The risk is amplified because the command runs in the OpenClaw environment and has access to the long-lived Home Assistant bearer token through `HASS_TOKEN`. ### Attack Path 1. An attacker supplies a smart-home request containing a single quote followed by shell syntax and an operating-system command. 2. The agent substitutes that request directly into the documented `curl` command in place of `USER REQUEST HERE`. 3. The single quote closes the intended `--data` shell argument. 4. Shell metacharacters in the remaining input cause the injected command to be parsed separately. 5. The injected command executes with the same operating-system identity and permissions as the OpenClaw process. 6. The attacker may use this access to read environment variables, disclose `HASS_TOKEN`, modify accessible files, or execute further local actions. Exploitation depends on the agent or runtime implementing the documented placeholder through unsafe shell-text substitution. A ...[truncated 938 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Do not insert user-controlled text into a shell command template. Construct the request body with a JSON-aware encoder and pass it as a quoted variable without evaluation. For example: ```bash payload=$(jq -n \ --arg text "$USER_REQUEST" \ --arg language "en" \ '{text: $text, language: $language}') curl -sS -X POST "$HASS_SERVER/api/conversation/process" \ -H "Authorization: Bearer $HASS_TOKEN" \ -H "Content-Type: application/json" \ --data-binary "$payload" ``` Apply the following hardening measures: 1. Pass the request through a positional argument, environment variable, standard input, or structured command API rather than textual command substitution. 2. Use a JSON serializer such as `jq` or an equivalent language library to encode all request fields. 3. Explicitly prohibit `eval`, `sh -c`, dynamically generated shell scripts, and direct replacement of placeholders inside command strings. 4. Prefer an implementation in which the process executable and arguments are passed as an argument array without invoking a shell. 5. Validate that `HASS_SERVER` uses an expected HTTPS origin and is not derived from untrusted request content. 6. Use a dedicated Home Assistant token with the minimum permissions available, and rotate the token if command injection or token exposure is suspected. 7. Add tests containing single quotes, double quotes, command substitutions, newlines, and shell metacharacters to verify that they remain literal JSON data. ]]>
