T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:100
- Finding
- Shell Command Injection Through User-Controlled CLI Arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 100–106 **Vulnerability Type**: Command injection through unsafe shell interpolation **Risk Level**: High ### Vulnerable Code ```markdown - Log pee: - `excretion log pee --start-at "..." --duration-sec 60 --color yellow --pain 0 --notes "..."` - Log poop: - `excretion log poop --start-at "..." --duration-sec 180 --color normal_brown --pain 1 --bristol 4 --notes "..."` ``` ### Technical Analysis The skill directs the Agent to construct CLI commands containing values derived from chat input, including `--start-at` and `--notes`. The instructions do not require structured process invocation, argument arrays, or shell-safe escaping. Wrapping a value in double quotes does not prevent shell evaluation. Shell substitutions such as `$(command)` and backtick expressions remain active inside double-quoted strings. If the Agent builds and executes the documented command through a shell, an attacker can place shell syntax in a note or another interpolated field. For example, a note containing the following value would remain executable if directly inserted into the documented template: ```text $(touch /tmp/excretion-command-injection) ``` The resulting command could resemble: ```bash excretion log pee --start-at "2026-03-01 10:10" \ --duration-sec 60 --color yellow --pain 0 \ --notes "$(touch /tmp/excretion-command-injection)" ``` The shell evaluates the command substitution before invoking the tracker. The Python CLI itself uses parameterized SQL and does not cause this issue; the vulnerability exists in the Agent-facing command-construction instructions. ### Attack Path 1. An attacker or untrusted user asks the Agent to log a bathroom event. 2. The attacker supplies a required or optional textual field containing shell metacharacters, such as a note with `$(command)`. 3. The Agent follows `SKILL.md` and interpolates the supplied value into the documented shell command. 4. The Agen ...[truncated 869 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Never construct a shell command by concatenating or interpolating user-controlled values. - Invoke the CLI through a structured argument array with shell processing disabled. For example: ```python subprocess.run( [ "python3", "scripts/excretion.py", "log", "pee", "--start-at", start_at, "--duration-sec", str(duration_sec), "--color", color, "--pain", str(pain), "--notes", notes, ], check=True, shell=False, ) ``` - Update `SKILL.md` to explicitly prohibit execution through `sh -c`, `bash -c`, or equivalent shell wrappers. - Treat every chat-derived value as untrusted, including timestamps, notes, colors, durations, and generated filenames. - Validate values against strict formats and length limits before invocation. - If shell invocation is unavoidable, use a well-tested platform-specific quoting mechanism for every untrusted argument; structured invocation should remain the preferred solution. - Add tests using payloads containing `$()`, backticks, quotes, semicolons, newlines, pipes, and redirection operators. ]]>
