T09 ยท Insecure Skill Coding Practices
Error
- Location
- scripts/vm-check.sh:16
- Finding
- SSH Option Injection Through Unquoted Command Construction## Vulnerability Details **File Location**: `scripts/vm-check.sh:16-28` **Vulnerability Type**: SSH option injection and potential local command execution **Risk Level**: High ```bash SSH_KEY="${SSH_KEY:-~/.ssh/id_rsa}" VM_HOST="${VM_HOST:?VM_HOST is required. Set it via: VM_HOST=<host> bash vm-check.sh}" VM_USER="${VM_USER:-ubuntu}" SECTION="${1:-all}" SSH_CMD="ssh -i $SSH_KEY -o StrictHostKeyChecking=no $VM_USER@$VM_HOST" run_section() { local name="$1" local cmd="$2" echo "=== $name ===" $SSH_CMD "$cmd" 2>/dev/null echo "" } ``` The same unsafe expansion pattern is also used for direct SSH calls at lines 69, 82, 96, 99, and 100. ### Technical Analysis The script constructs an SSH invocation as a scalar string and subsequently expands `$SSH_CMD` without quotes. Bash performs word splitting and pathname expansion on this value. Consequently, whitespace and option-like content supplied through `SSH_KEY`, `VM_USER`, or `VM_HOST` can become additional arguments to the local `ssh` process. This is particularly dangerous because OpenSSH supports options such as `ProxyCommand`, which can cause a local process to be launched. An attacker who can influence the saved VM configuration or the environment passed to the script could place additional SSH options in one of these values. The script performs no validation to ensure that the key is a single path, that the username and hostname have valid syntax, or that injected options are rejected. Although the Skill requires SSH access for its declared VM-checking functionality, accepting arbitrary SSH arguments is not necessary and exceeds the minimum safe behavior. ### Attack Path 1. An attacker influences a VM configuration value stored in `TOOLS.md`, or otherwise controls an environment variable such as `SSH_KEY`. 2. The Agent extracts that value and passes it to `vm-check.sh`. 3. The value includes whitespace followed by an additional SSH op ...[truncated 1043 chars]
- Remediation
- ## Remediation Suggestions Construct the SSH command as a Bash array so that every value remains exactly one argument: ```bash SSH_KEY="${SSH_KEY:-$HOME/.ssh/id_rsa}" SSH_CMD=( ssh -i "$SSH_KEY" -o StrictHostKeyChecking=yes -- "$VM_USER@$VM_HOST" ) run_section() { local name="$1" local cmd="$2" echo "=== $name ===" "${SSH_CMD[@]}" "$cmd" echo } ``` Apply the array form to every SSH invocation rather than expanding a command string. In addition: - Validate `VM_USER` against the syntax allowed for expected remote usernames. - Validate `VM_HOST` as a hostname, IPv4 address, or IPv6 address and reject whitespace, control characters, and leading hyphens. - Require `SSH_KEY` to resolve to an expected regular file and reject newline or control characters. - Use `$HOME/.ssh/id_rsa` rather than a literal tilde inside parameter expansion. - Treat values recovered from `TOOLS.md` as untrusted configuration rather than shell-safe text. - Preserve SSH errors or report them safely instead of suppressing all diagnostics with `2>/dev/null`.
