T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:72
- Finding
- Command Injection Through Unvalidated Skill Names, Slugs, and Usernames<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:72`, `SKILL.md:86`, `SKILL.md:103-107`, and `SKILL.md:114`; duplicated in the Chinese section at `SKILL.md:234`, `SKILL.md:248`, `SKILL.md:265-269`, and `SKILL.md:276` **Vulnerability Type**: Shell command injection through unquoted, user-derived values **Risk Level**: High ### Vulnerable Code ```bash clawhub skill publish ./<skill-name> --dry-run ``` ```bash grep -in "AIzaSy\|sk-\|password\|secret\|@gmail\|@qq\|/home/\|192\.168" ./<skill-name>/SKILL.md ``` ```bash export PATH="$PATH:$(npm root -g)/.bin" clawhub skill publish ./<skill-name> \ --slug <slug> \ --name "<Display Name>" \ --version <new-version> ``` ```bash clawhub inspect <username>/<skill-name> ``` Equivalent vulnerable command templates are repeated at lines 234, 248, 265-269, and 276. ### Technical Analysis The workflow collects the skill name and related publication metadata from the user and later inserts those values into shell commands. The placeholders for `<skill-name>`, `<slug>`, `<username>`, and `<new-version>` are not quoted, and the document does not require strict validation before command execution. If an agent performs direct textual substitution, whitespace, shell metacharacters, command substitutions, redirections, or option-like values can change the intended command structure. Quoting `<Display Name>` alone is insufficient because the other user-derived values remain exposed. Quoting must also be paired with validation because command arguments beginning with `-` may still be interpreted as options by invoked programs. The dry-run and privacy-scan commands occur before the stated publication confirmation step. Consequently, requiring confirmation before final publication does not fully mitigate command injection in earlier workflow stages. ### Attack Path 1. An attacker supplies a crafted skill name, slug, username, or version during requirement gathering. 2. The agent generates a directory or co ...[truncated 1472 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Validate every user-controlled identifier before using it in a path or command. For skill names and slugs, enforce a restrictive rule such as: ```text ^[a-z0-9]+(?:-[a-z0-9]+)*$ ``` 2. Define similarly restrictive allowlists for usernames and versions. Semantic versions should be parsed and validated rather than passed through as arbitrary strings. 3. Reject values containing whitespace, path separators, `..`, shell metacharacters, control characters, or leading hyphens. 4. Quote all substituted shell arguments: ```bash clawhub skill publish "./${skill_name}" --dry-run grep -in \ 'AIzaSy\|sk-\|password\|secret\|@gmail\|@qq\|/home/\|192\.168' \ "./${skill_name}/SKILL.md" clawhub skill publish "./${skill_name}" \ --slug "${slug}" \ --name "${display_name}" \ --version "${version}" clawhub inspect "${username}/${skill_name}" ``` 5. Prefer invoking commands through a structured process API with an argument array instead of constructing a shell command string. Disable shell interpretation where the execution environment supports it. 6. Resolve and verify generated paths before use. Confirm that the target remains inside the intended `clawhub-skills` directory. 7. Require explicit confirmation before executing any command derived from user input, including dry-run validation and privacy scanning—not only before final publication. 8. Apply the same changes to both duplicated language sections so that neither version preserves the vulnerable templates. ]]>
