T09 · Insecure Skill Coding Practices
- Location
- SKILL.md:34
- Finding
- Shell Command Injection Through Unescaped User-Controlled JSON Values<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:34-40`, `SKILL.md:63-72`, and `SKILL.md:95-102` **Vulnerability Type**: User-controlled values interpolated into shell command templates **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 unsafe construction pattern is used for continuous monitoring: ```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 workflow: ```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 instructs an agent to execute shell commands and replace `STREAM_URL_HERE` and `NATURAL_LANGUAGE_CONDITION_HERE` with values supplied through conversation. Those values are placed inside a single-quoted shell argument rather than being serialized by a JSON library. A single quote in an attacker-controlled value can terminate the shell quoting context. Additional shell syntax can then be appended and interpreted as a local command. JSON escaping alone would not prevent this issue because shell parsing occurs before the request is sent. This behavior is not necessary for the declared functionality. Sending a URL and condition to the Trio API i ...[truncated 1854 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not interpolate user-controlled values into shell command text. 2. Prefer a structured JavaScript or Python HTTP client that accepts the stream URL and condition as data values and serializes the JSON body internally. 3. If curl must be retained, construct the body with a JSON-aware tool and pass it as a file: ```bash payload_file="$(mktemp)" trap 'rm -f "$payload_file"' EXIT jq -n \ --arg stream_url "$STREAM_URL" \ --arg condition "$CONDITION" \ '{ stream_url: $stream_url, condition: $condition }' > "$payload_file" 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 "@$payload_file" ``` 4. Pass values through environment variables or fixed argument arrays rather than generating a shell program dynamically. 5. Validate stream URLs against explicitly supported schemes. Reject shell metacharacters only as defense in depth; validation must not replace correct argument handling. 6. Apply the same correction to the check-once, live-monitor, and live-digest examples. 7. Run the agent with a restricted operating-system account, a minimal environment, limited filesystem access, and constrained outbound network access to reduce impact if another injection flaw is introduced. 8. Add automated tests using quotes, newlines, command substitutions, semicolons, and other shell metacharacters to verify that inputs remain data rather than executable syntax. ]]>
