T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:56
- Finding
- Shell Command Injection Through Untrusted Publish Parameters<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:56-66`; duplicated in `templates/publish_review_report.md:72-84` **Vulnerability Type**: Shell command injection through unsafe command generation **Risk Level**: High ### Vulnerable Code ```markdown 1. **识别对象**:路径、skill/plugin、目标 owner、registry latest;未知项写“未提供”。 2. **选择模式**:遵循 auto 规则,或尊重用户显式指定的 quick/deep。 3. **收集证据**:只把读到或执行到的结果记为事实;推断单独标注。 4. **运行检查**:按模式检查结构、版本、页面、环境、安全与发布动作。 5. **给出结论**: - `可以发`:无 P0,关键证据一致 - `补完再发`:无致命结构问题,但存在发布前应修复项 - `先别发`:存在 P0、安全风险、身份冲突或证据互相矛盾 6. **生成命令**: - Skill:`clawhub skill publish <path> --slug <stable-slug> --name "<Human Readable Name>" --dry-run --owner <owner>` - Plugin:先 `clawhub package validate <path>`,再 `clawhub package publish <path> --dry-run` ``` The report template repeats the affected command construction: ```bash clawhub skill publish <path> --slug <stable-slug> --name "<Human Readable Name>" --dry-run --owner <owner> clawhub package validate <path> clawhub package publish <path> --dry-run ``` ### Technical Analysis The Skill instructs the agent to identify package paths, slugs, display names, and owners and then place those values into shell command templates. These values can originate from user input, filesystem names, or package metadata and must therefore be treated as untrusted. The path, slug, and owner placeholders are not quoted. Although the display name is surrounded by double quotes, double quotes do not prevent shell command substitution through constructs such as `$(command)` or backticks. The instructions define neither strict character validation nor a shell-safe escaping mechanism. If the agent replaces the placeholders with untrusted values and the resulting text is subsequently executed in a shell, shell syntax can be interpreted before the `clawhub` process starts. The presence of `--dry-run` does not mitigate this issue because shell expansion and command substitution occur before `clawhub` receives its arg ...[truncated 1522 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not generate executable shell strings from package metadata or user input. Where tool execution is supported, invoke the process with a structured argument array, for example conceptually: ```text ["clawhub", "skill", "publish", path, "--slug", slug, "--name", displayName, "--dry-run", "--owner", owner] ``` 2. Validate every dynamic field before use: - Restrict slugs and owners to an explicitly documented allowlist such as lowercase letters, digits, and hyphens. - Reject control characters, newlines, null bytes, and shell metacharacters. - Resolve and validate paths separately rather than applying a slug-oriented rule to them. - Reject ambiguous values beginning with `-` where they could be interpreted as command options. 3. If a shell command must be displayed for manual use, apply robust POSIX shell quoting independently to every dynamic argument. Do not rely on simple double quotes. 4. Clearly label generated commands as untrusted previews unless all inserted values have passed validation and quoting. 5. Add tests using paths and metadata containing spaces, single and double quotes, semicolons, newlines, redirects, pipes, `$()`, backticks, wildcard characters, and leading hyphens. Verify that no value can create additional commands or unintended arguments. 6. Apply the same correction to both `SKILL.md` and `templates/publish_review_report.md` so the primary workflow and report template cannot diverge. ]]>
