T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/port.sh:83
- Finding
- Unvalidated Port Input Can Alter Process Selection and Terminate Unintended Processes## Vulnerability Details **File Location**: `scripts/port.sh`, lines 83-105 **Vulnerability Type**: Shell argument injection and unsafe process termination **Risk Level**: High ### Vulnerable Code ```bash free() { local port=$1 if [ -z "$port" ]; then echo "用法: port free <端口>" return 1 fi # 获取占用进程 local pid=$(lsof -t -i :$port 2>/dev/null) if [ -z "$pid" ]; then echo "端口 $port 没有被占用" return 1 fi local pname=$(ps -p $pid - comm= 2>/dev/null | head -1) echo "⚠️ 端口 $port 被 $pname (PID: $pid) 占用" echo "是否释放? (y/n)" read -r confirm if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then kill $pid echo "✅ 已释放端口 $port (终止了进程 $pid)" else echo "❌ 已取消" fi } ``` ### Technical Analysis The `port` parameter is checked only for emptiness. It is not restricted to a decimal TCP/UDP port in the valid range of 1 through 65535. The value is expanded without quotes in: ```bash lsof -t -i :$port ``` Shell word splitting therefore allows a port argument containing whitespace to become multiple arguments to `lsof`. Additional tokens may be interpreted as `lsof` selection options rather than as part of the requested port specification. This can change or broaden the set of processes returned. The resulting `pid` value is also expanded without validation or quoting in `ps` and `kill`. If `lsof` returns multiple process IDs, `kill $pid` attempts to terminate all of them after confirmation. The script does not verify that each value is a numeric PID, that the process still owns the requested port, or that the process shown to the user is the same process terminated. Related functions in this file reuse the same unsafe pattern at lines 27, 68, 92, 99, 105, 121, 124, 138, 164, and 179. The allocation path at lines 155-169 additionally places an unvalid ...[truncated 1478 chars]
- Remediation
- ## Remediation Suggestions 1. Validate every supplied port before using it: ```bash validate_port() { case "$1" in ''|*[!0-9]*) return 1 ;; esac [ "$1" -ge 1 ] && [ "$1" -le 65535 ] } ``` 2. Reject invalid values before invoking `lsof`, performing arithmetic, recording data, or terminating processes: ```bash if ! validate_port "$port"; then printf '%s\n' "Invalid port: expected an integer from 1 to 65535" >&2 return 1 fi ``` 3. Quote all parameter expansions: ```bash pid_output=$(lsof -t -i ":$port" 2>/dev/null) ``` 4. Parse the result one PID at a time and require every value to match `^[0-9]+$`. 5. Before termination, repeat the port lookup and verify that each PID still owns the requested listening socket. This reduces time-of-check/time-of-use risk and PID reuse issues. 6. Display and confirm every selected PID individually. Do not display only the first process and then terminate the entire PID list. 7. Use `kill -- "$pid"` where supported, check its exit status, and report success only when termination actually succeeds. 8. Apply the same validation to `record`, `query`, `check`, and `allocate`. Convert a validated decimal value before arithmetic rather than evaluating an arbitrary user-provided expression.
