T09 · Insecure Skill Coding Practices
- Location
watchdog.sh:238- Finding
Shell Command Injection Through the TCP Check Fallback
- Content
View full analysis
/dev/tcp/${host}/${port}" 2>/dev/null; then success=true fi fi ``` The values reaching the vulnerable operation are read from the configuration without validation: ```bash host=$(echo "$svc" | jq -r '.host') port=$(echo "$svc" | jq -r '.port') timeout_ms=$(echo "$svc" | jq -r ".timeout_ms // $DEFAULT_TIMEOUT_MS") result=$(check_tcp "$host" "$port" "$timeout_ms") ``` ### Technical Analysis The `host` and `port` values originate in `watchdog.json`. When neither `nc` nor `ncat` is installed, they are interpolated directly into a command string passed to `bash -c`. Quoting the overall argument to `bash -c` does not make the interpolated content safe. Shell metacharacters contained in either value become part of the command text parsed by the newly launched shell. An attacker capable of modifying or supplying the watchdog configuration can therefore introduce command substitutions, command separators, redirections, or pipelines. For example, a malicious host value containing shell syntax could cause an additional command to run when the fallback is reached. Exploitation depends on the absence of both `nc` and `ncat`, but the fallback is explicitly supported and documented by the Skill. ### Attack Path 1. An attacker gains the ability to create or modify the JSON configuration used by the Skill, including through a user-provided `--config` path or `WATCHDOG_CONFIG`. 2. The attacker defines a TCP service and inserts shell metacharacters into its `host` or `port` field. 3. The user or Agent invokes `watchdog.sh` as documented. 4. The target environment does not have `nc` or `ncat`, causing execution to enter the `/dev/tcp` fallback. 5. The untrusted values are interpolated into the string passed to ...[truncated 718 chars]- Remediation
View remediation
= 1 && port <= 65535 )) || { echo "fail|0|Invalid TCP port" return } [[ "$host" =~ ^[A-Za-z0-9._:-]+$ ]] || { echo "fail|0|Invalid TCP host" return } if timeout "$timeout_s" bash -c \ 'exec 3<>"/dev/tcp/$1/$2"' bash "$host" "$port" 2>/dev/null; then success=true fi ``` The hostname validation should be made more precise if internationalized names or IPv6 zone identifiers must be supported. ]]>
