T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/v2ray-proxy.sh:173
- Finding
- Shell Command Injection Through eval in the Command Wrapper<![CDATA[ ## Vulnerability Details **File Location**: `scripts/v2ray-proxy.sh:173-190` **Vulnerability Type**: Shell command injection **Risk Level**: High ### Vulnerable Code ```bash wrap() { local cmd="$*" log_info "执行命令: $cmd" # 检查是否需要代理 if check_network; then log_info "网络正常,直接执行..." eval "$cmd" return $? fi # 需要代理,开启后执行 log_info "开启代理后执行..." proxy_on local result=0 eval "$cmd" || result=$? ``` ### Technical Analysis The `wrap` function combines all command arguments into one string using `$*` and then passes that string to `eval`. Unlike direct array-based command execution, `eval` parses the reconstructed string as shell source code. Shell metacharacters, command substitutions, redirections, pipelines, and additional statements embedded in any argument are therefore interpreted as executable syntax. Although `wrap` is intentionally a command-execution interface, using `eval` destroys the original argument boundaries. This creates an injection vulnerability when a trusted caller or agent constructs a wrapped command containing untrusted data, such as a URL, filename, branch name, API parameter, or user-provided search term. Both the direct-connect and proxy-enabled execution paths use the same unsafe operation. ### Attack Path 1. A trusted process invokes `v2ray-proxy.sh wrap` to run an otherwise legitimate command. 2. An attacker controls part of an argument passed to that command. 3. The attacker inserts shell syntax, such as `;`, `$(...)`, a pipeline, or output redirection. 4. `local cmd="$*"` flattens the command and its arguments into a single string. 5. `eval "$cmd"` reparses the attacker-controlled syntax as shell code. 6. The injected command executes with the privileges and environment of the user running the skill. For example, if an untrusted value is passed as a single intended URL argument: ```bash ./scripts/v2ray-proxy.sh wrap curl 'https://example.i ...[truncated 636 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Preserve the original argument array and execute it directly without `eval`: ```bash wrap() { if [ "$#" -eq 0 ]; then log_error "No command specified" return 2 fi log_info "Executing command: $(printf '%q ' "$@")" if check_network; then "$@" return $? fi proxy_on local result=0 "$@" || result=$? proxy_off return "$result" } ``` Additional hardening measures: - Never reconstruct executable commands from `$*`. - Do not use `eval`, `bash -c`, or `sh -c` for argument forwarding. - Treat URLs, filenames, repository names, and other externally supplied values as untrusted. - If only a limited set of commands is required, enforce an explicit executable allowlist. - Add tests containing spaces, semicolons, command substitutions, redirections, and newline characters to confirm that arguments remain literal. ]]>
