T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:41
- Finding
- Shell Command Injection Through Unquoted Raw Secret Parameters<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 5 and 41–45 **Vulnerability Type**: T09: Insecure Skill Coding Practices **Risk Level**: High ### Vulnerable Code ```yaml command-arg-mode: raw ``` ```bash export GITHUB_TOKEN="$AGENT_GITHUB_PAT" gh workflow run set-secret.yml \ --repo "$MANAGE_SECRETS_GITHUB_REPO" \ -f persona=<PERSONA> \ -f secret_key=<KEY> \ -f secret_value=<VALUE> ``` ### Technical Analysis The skill uses raw command argument dispatch and instructs the agent to insert `PERSONA`, `KEY`, and `VALUE` directly into a shell command without shell-safe quoting. The secret value is inherently user-controlled because the skill exists to accept a credential supplied for storage. If the documented placeholders are replaced through direct textual interpolation, shell metacharacters in a supplied value can be interpreted by the shell rather than passed as part of a single argument. Relevant payload constructs include command substitution, command separators, redirections, and shell expansions. Validation is documented for `KEY`, but no equivalent validation or shell-safe transport is defined for `VALUE`. Quoting the repository variable does not protect the unquoted placeholders. ### Attack Path 1. An attacker or untrusted user asks the agent to set a secret containing shell syntax, such as a command substitution or command separator. 2. The agent inserts the supplied value into the documented `<VALUE>` placeholder. 3. Because `command-arg-mode` is `raw` and the resulting value is not quoted or passed through a shell-free argument interface, the local shell interprets the injected syntax. 4. The injected command executes with the permissions and environment of the agent process. 5. The malicious process may read `AGENT_GITHUB_PAT`, access files available to the agent, invoke GitHub APIs, or tamper with repositories and deployment resources accessible through existing credentials. Exploitation depends on the runtime p ...[truncated 1019 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not generate a shell command by interpolating raw values. Invoke `gh` through a structured subprocess API with an explicit argument array and with shell execution disabled. 2. If shell execution is unavoidable, pass dynamic values through positional parameters rather than embedding them into command text. Do not rely on ad hoc escaping. 3. Validate `PERSONA` and `KEY` against strict allowlists before invocation. Continue enforcing `^[A-Z][A-Z0-9_]*$` for keys and define a similarly restrictive persona format. 4. Treat `VALUE` as arbitrary binary or text data. Do not attempt to make it safe through character filtering alone, because legitimate secrets may contain shell metacharacters. 5. Replace `command-arg-mode: raw` with a structured command mode where supported. 6. Run the skill under a minimally privileged identity and use a fine-grained GitHub token limited to the required repository and workflow permissions. 7. Add regression tests using values containing spaces, quotes, semicolons, dollar signs, backticks, newlines, and command-substitution syntax. Verify that each value reaches GitHub as data and never executes locally. ]]>
