T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:49
- Finding
- Shell Command Injection Through User-Controlled Keyword Arguments<. **Keyless live-SERP sampling**: `python3 "${CLAUDE_PLUGIN_ROOT}/scripts/connectors/firecrawl.py" search "<candidate keyword>" --limit 10` (Firecrawl keyless free tier, ~1,000 credits/mo, no key needed) shows who actually ranks for a candidate — feed the top-10 domains and formats into the intent check and the difficulty read as **Measured** evidence instead of guessing. Volume still needs `~~SEO tool` or GSC. **Keyless topic-demand proxy**: `python3 "${CLAUDE_PLUGIN_ROOT}/scripts/connectors/pageviews.py" "<Topic_Article>" --months 12` returns a topic's real Wikipedia-attention series — Measured direction and seasonality evidence when no volume tool is connected. It is *attention, not search volume*: use it to rank topics against each other and time them, never to quote a volume number. ``` ### Technical Analysis The skill instructs the agent to place user-derived seed keywords, candidate keywords, and topic names directly inside shell command strings. Double-quoting these values does not prevent command substitution. Shell constructs such as `$(...)` and backticks are still evaluated inside double quotes. If the agent replaces one of these placeholders with untrusted input and executes the resulting command through a shell, the shell can evaluate attacker-controlled substitutions before invoking the intended Python helper. Quoting may also become ineffective if the supplied valu ...[truncated 1873 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not construct a shell command by interpolating user-controlled values. 2. Invoke each helper through a process API that accepts an argument array and does not start a shell. For example, pass the executable and arguments as separate values equivalent to: ```text ["python3", helper_path, user_seed, "--expand"] ``` 3. If the agent host exposes only a shell-command interface, add a trusted wrapper that accepts structured input and invokes the helper with a non-shell subprocess API. 4. Validate the topic or keyword against an explicit policy before execution. Reject control characters and unexpected shell metacharacters rather than relying on quoting alone. 5. Keep `${CLAUDE_PLUGIN_ROOT}` under trusted host control, resolve the helper path canonically, and verify that it remains within the expected scripts directory. 6. Document that keyword values must never be concatenated into shell strings. 7. Add regression tests containing spaces, quotes, backticks, `$()`, semicolons, newlines, and option-like values to verify that every value is passed only as inert data. 8. Consider inserting `--` before positional user input where the helper supports it, preventing values beginning with `-` from being interpreted as options. ]]>
