T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/setup.sh:17
- Finding
- Shell Command Injection Through Generated Environment Configuration<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh`, lines 17–27, 58–75, and 118 **Vulnerability Type**: Shell command injection through unsafe configuration generation **Risk Level**: High ### Vulnerable Code ```bash if [ -z "$DETECTED_WIN_ROOT" ]; then echo "WARNING: Could not auto-detect Windows Python. Please enter path manually." echo "" read -p "Windows root (e.g. D:\ or /mnt/d): " WIN_ROOT_INPUT WIN_ROOT="$WIN_ROOT_INPUT" else echo "Detected Windows root: $DETECTED_WIN_ROOT" WIN_ROOT="$DETECTED_WIN_ROOT" read -p "Python path [default: $WIN_ROOT/app/anaconda/python.exe]: " PYTHON_INPUT PYTHON_INPUT="${PYTHON_INPUT:-$WIN_ROOT/app/anaconda/python.exe}" fi if [[ "$PYTHON_INPUT" == /mnt/* ]]; then PYTHON_PATH="$PYTHON_INPUT" elif [[ "$PYTHON_INPUT" == /* ]]; then PYTHON_PATH=$(wslpath -w "$PYTHON_INPUT" 2>/dev/null || echo "$PYTHON_INPUT") else PYTHON_PATH="$PYTHON_INPUT" fi ``` ```bash cat > "$OPENCLAW_ENV" << ENVEOF #!/bin/bash # === wsl-windows-bridge environment === # Auto-generated at $(date -u +%Y-%m-%dT%H:%M:%SZ) export WIN_BIN="\$HOME/.openclaw/bin" export PATH="\$WIN_BIN:\$PATH" export WIN_ROOT="$WIN_ROOT" export WIN_ANACONDA="$WIN_ROOT/app/anaconda" export WIN_SCRIPTS="$WIN_ROOT/app/scripts" export WIN_PROJECT="$WIN_ROOT/app/project" export WIN_PYTHON="$PYTHON_PATH" export WIN_PS="/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" export WIN_CMD="/mnt/c/Windows/System32/cmd.exe" ``` ```bash source "$OPENCLAW_ENV" 2>/dev/null ``` ### Technical Analysis The installer accepts an interactive Windows root or Python path and interpolates that value directly into an executable shell configuration file. No validation or shell-safe escaping is applied before constructing assignments such as: ```bash export WIN_ROOT="$WIN_ROOT" export WIN_PYTHON="$PYTHON_PATH" ``` An input containing a double quote followed by shell syntax can terminate the generated assignment and append ...[truncated 2077 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Use shell-safe serialization for generated assignments.** Generate every environment value with `printf %q` rather than embedding it in a heredoc: ```bash { printf '#!/bin/bash\n' printf 'export WIN_BIN=%q\n' "$HOME/.openclaw/bin" printf 'export PATH="$WIN_BIN:$PATH"\n' printf 'export WIN_ROOT=%q\n' "$WIN_ROOT" printf 'export WIN_ANACONDA=%q\n' "$WIN_ROOT/app/anaconda" printf 'export WIN_SCRIPTS=%q\n' "$WIN_ROOT/app/scripts" printf 'export WIN_PROJECT=%q\n' "$WIN_ROOT/app/project" printf 'export WIN_PYTHON=%q\n' "$PYTHON_PATH" printf 'export WIN_PS=%q\n' "/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" printf 'export WIN_CMD=%q\n' "/mnt/c/Windows/System32/cmd.exe" } > "$OPENCLAW_ENV" ``` 2. **Validate input against expected path formats.** Reject control characters and values outside supported WSL or Windows path patterns. Validation should occur before writing the configuration: ```bash if [[ "$PYTHON_INPUT" == *$'\n'* || "$PYTHON_INPUT" == *$'\r'* ]]; then echo "ERROR: Path contains invalid control characters." >&2 exit 1 fi ``` A stricter allowlist should be used where practical. 3. **Do not immediately source generated executable configuration.** Perform verification using local variables or invoke tools directly after validation. This reduces the impact of any future serialization defect. 4. **Prefer a non-executable data format.** Store paths in a format such as JSON and load them with a parser instead of generating shell code from user input. 5. **Write the configuration atomically with restrictive permissions.** Create a temporary file using `mktemp`, set permissions to `0600`, validate its contents, and atomically rename it into place. ]]>
