T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:33
- Finding
- Shell Command Injection Through User-Controlled Stream URLs and Conditions<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:33-40`, `SKILL.md:62-72`, and `SKILL.md:94-102` **Vulnerability Type**: Shell command injection caused by unsafe interpolation into single-quoted JSON **Risk Level**: High ### Vulnerable Code ```bash curl -s -X POST "https://trio.machinefi.com/api/check-once" \ -H "Authorization: Bearer $TRIO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "stream_url": "STREAM_URL_HERE", "condition": "NATURAL_LANGUAGE_CONDITION_HERE" }' | python3 -m json.tool ``` The same construction pattern appears in the continuous-monitoring action: ```bash curl -s -X POST "https://trio.machinefi.com/api/live-monitor" \ -H "Authorization: Bearer $TRIO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "stream_url": "STREAM_URL_HERE", "condition": "NATURAL_LANGUAGE_CONDITION_HERE", "interval_seconds": 10, "monitor_duration_seconds": 600, "max_triggers": 1 }' | python3 -m json.tool ``` It also appears in the digest action: ```bash curl -s -X POST "https://trio.machinefi.com/api/live-digest" \ -H "Authorization: Bearer $TRIO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "stream_url": "STREAM_URL_HERE", "window_minutes": 10, "capture_interval_seconds": 60 }' | python3 -m json.tool ``` ### Technical Analysis The Skill directs the agent to replace `STREAM_URL_HERE` and `NATURAL_LANGUAGE_CONDITION_HERE` with values supplied through user conversation and then execute the resulting command in a shell. These values are placed inside a single-quoted shell argument. A single quote in an attacker-controlled value can terminate the quoted JSON argument. Additional shell metacharacters can then introduce a new command. Escaping a value for JSON is not sufficient because JSON and POSIX shell quoting are separate parsing layers. The issue affects both nominal URL input and free-form natural-language conditions. The latter is particularly exposed becaus ...[truncated 2077 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not insert user-controlled text directly into shell command templates. 2. Prefer the structured JavaScript handler described in `IMPLEMENTATION_GUIDE.md`, where request bodies are constructed with `JSON.stringify` and sent through `fetch`. 3. If shell-based operation must be retained, construct JSON with a tool that accepts data as arguments rather than source code. For example, pass values through environment variables and serialize them with Python: ```bash STREAM_URL="$USER_STREAM_URL" CONDITION="$USER_CONDITION" python3 - <<'PY' | import json import os print(json.dumps({ "stream_url": os.environ["STREAM_URL"], "condition": os.environ["CONDITION"] })) PY curl --fail-with-body --silent --show-error \ -X POST "https://trio.machinefi.com/api/check-once" \ -H "Authorization: Bearer $TRIO_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- ``` 4. Prefer direct subprocess invocation with an argument array and with shell evaluation disabled. 5. Validate stream URLs against an explicit scheme allowlist such as `https`, `rtsp`, and `rtsps`. Reject control characters and malformed URLs, but do not treat validation as a substitute for safe command construction. 6. Apply length limits to stream URLs, conditions, webhook URLs, and option fields. 7. Run the Skill in a restricted environment with minimal filesystem access, a limited environment-variable set, and constrained outbound networking. 8. Add automated tests containing apostrophes, newlines, command separators, command substitutions, and other shell metacharacters to verify that input remains data rather than executable syntax. ]]>
