T09 · Insecure Skill Coding Practices
Error
- Location
- skill.yaml:41
- Finding
- Shell Command Injection Through Unquoted Trigger Parameters<![CDATA[ ## Vulnerability Details **File Location**: `skill.yaml`, lines 41–70 **Vulnerability Type**: Untrusted command argument interpolation **Risk Level**: High ### Vulnerable Code ```yaml - trigger: "更新接口文档,用 (.+)" description: "导出指定项目的接口文档(团队用默认)" action: "node script/auto-export-playwright.js --project=$1" - trigger: "更新接口文档,团队是 (.+),项目是 (.+)" description: "导出指定团队和项目的接口文档" action: "node script/auto-export-playwright.js --team=$1 --project=$2" - trigger: "更新接口文档 - (.+)" description: "导出指定项目的接口文档(简写)" action: "node script/auto-export-playwright.js --project=$1" - trigger: "更新接口文档 - (.+) - (.+)" description: "导出指定团队和项目的接口文档(简写)" action: "node script/auto-export-playwright.js --team=$1 --project=$2" ``` ### Technical Analysis The trigger expressions use unrestricted `(.+)` capture groups and interpolate the resulting values directly into command strings. The captured project and team names are neither quoted nor validated. If the skill runtime executes the `action` field through a command shell, an attacker can include shell metacharacters, command substitutions, redirections, or additional command separators in a trigger parameter. The shell would then interpret those characters as command syntax rather than as part of a project name. The JavaScript argument parser does not mitigate this issue because command injection would occur in the shell before Node.js receives `process.argv`. ### Attack Path 1. An attacker supplies a trigger containing shell syntax in the team or project capture. 2. The unrestricted regular expression captures the complete attacker-controlled value. 3. The runtime substitutes the value into the `action` command. 4. A shell interprets the injected metacharacters. 5. The injected command executes with the privileges and environment of the Agent process. Exploitability depends on whether the skill framework evaluates `action` through a shell. If it uses direct process execution with a structured argument ar ...[truncated 439 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Replace shell command strings with structured executable-and-argument declarations where supported. - Pass captured values as individual argument-array elements rather than concatenating them into a command. - Restrict team and project names to a conservative allowlist of expected Unicode letters, numbers, spaces, underscores, hyphens, and parentheses. - Reject shell metacharacters, control characters, newlines, redirection operators, and command-substitution syntax. - If shell execution cannot be avoided, use a platform-appropriate escaping library rather than implementing ad hoc quoting. - Add security tests using values containing `;`, `&&`, `|`, newlines, backticks, `$()`, quotes, and redirection operators. ]]>
