T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/cluster_health.sh:81
- Finding
- Arbitrary Command Execution Through K8S_REQUEST_TIMEOUT in cluster_health.sh<![CDATA[ ## Vulnerability Details **File Location**: `scripts/cluster_health.sh:7`, `scripts/cluster_health.sh:81-89`, and command construction at `scripts/cluster_health.sh:159`, `179`, and `200` **Vulnerability Type**: Shell command injection through an environment variable **Risk Level**: Critical ### Vulnerable Code ```bash REQUEST_TIMEOUT="${K8S_REQUEST_TIMEOUT:-15s}" ``` ```bash run_pipe_or_warn() { local description="$1" local cmd="$2" if ! bash -o pipefail -c "$cmd"; then warn_raw "${description} failed; continuing." CHECK_FAIL_COUNT=$((CHECK_FAIL_COUNT + 1)) return 1 fi return 0 } ``` The vulnerable function is invoked with command strings containing the environment-controlled value: ```bash run_pipe_or_warn "Cluster version" "kubectl --request-timeout=\"$REQUEST_TIMEOUT\" version --client=false 2>/dev/null || kubectl --request-timeout=\"$REQUEST_TIMEOUT\" version" ``` ```bash run_pipe_or_warn "Recent events query" "kubectl --request-timeout=\"$REQUEST_TIMEOUT\" get events --all-namespaces --sort-by='.lastTimestamp' | tail -50" ``` ```bash run_pipe_or_warn "Component readiness endpoint query" "kubectl --request-timeout=\"$REQUEST_TIMEOUT\" get --raw='/readyz?verbose' 2>/dev/null || kubectl --request-timeout=\"$REQUEST_TIMEOUT\" get --raw='/healthz?verbose' 2>/dev/null || kubectl --request-timeout=\"$REQUEST_TIMEOUT\" get componentstatuses" ``` ### Technical Analysis `K8S_REQUEST_TIMEOUT` is accepted without format validation. Its value is interpolated into a command string that is subsequently evaluated by a new shell through `bash -c`. The double quotes inserted around `$REQUEST_TIMEOUT` do not make this safe. An attacker who controls the environment can include quote characters and shell operators in the value, terminate the intended argument, and append another command. Because `bash -c` reparses the completed string as shell syntax, injected operators, redirections, substitutions, and command se ...[truncated 1580 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove `bash -c` and represent commands as argument arrays. 2. Implement pipelines directly in shell functions rather than constructing executable strings. 3. Validate `K8S_REQUEST_TIMEOUT` against an explicit allowlist pattern before use, for example: ```bash REQUEST_TIMEOUT="${K8S_REQUEST_TIMEOUT:-15s}" if [[ ! "$REQUEST_TIMEOUT" =~ ^[0-9]+(ms|s|m)$ ]]; then printf 'ERROR: Invalid K8S_REQUEST_TIMEOUT.\n' >&2 exit 2 fi ``` 4. Rewrite the event query without dynamic shell evaluation: ```bash recent_events() { kubectl_cmd get events --all-namespaces --sort-by=.lastTimestamp | tail -50 } run_or_warn "Recent events query" recent_events ``` 5. For fallback operations, use ordinary functions with explicit control flow: ```bash component_health() { kubectl_cmd get --raw='/readyz?verbose' 2>/dev/null || kubectl_cmd get --raw='/healthz?verbose' 2>/dev/null || kubectl_cmd get componentstatuses } run_or_warn "Component readiness endpoint query" component_health ``` 6. Add regression tests using timeout values containing quotes, semicolons, command substitutions, whitespace, and newline characters. Verify that invalid values are rejected and no marker command is executed. ]]>
