T09 · Insecure Skill Coding Practices
- Location
- scripts/claude-code-bridge.sh:136
- Finding
- Shell Command Injection Through the Working Directory Argument<![CDATA[ ## Vulnerability Details **File Location**: `scripts/claude-code-bridge.sh`, lines 136–172 **Vulnerability Type**: Shell command injection through unsafe command-string construction **Risk Level**: High ### Vulnerable Code ```bash local workdir="${MESSAGE:-}" local is_sandbox=0 if [[ "$workdir" == "--sandbox" || -z "$workdir" ]]; then # Sandbox mode: create a temporary directory workdir=$(mktemp -d /tmp/cc-sandbox-XXXXXX) is_sandbox=1 echo "$workdir" > "$SANDBOX_FLAG" else # Expand ~ to $HOME workdir="${workdir/#\~/$HOME}" fi # Verify that the directory exists if [[ ! -d "$workdir" ]]; then echo "[claude-code-bridge] ❌ Directory does not exist: $workdir" rm -f "$SANDBOX_FLAG" return 1 fi # Record the working directory echo "$workdir" > "$WORKDIR_FILE" # Build startup command local launch_cmd launch_cmd="cd '$workdir' && unset CLAUDECODE CLAUDE_CODE; export TERM=xterm-256color; exec '$CLAUDE_BIN'" # Start Claude inside tmux tmux new-session -d -s "$TMUX_NAME" -x 220 -y 50 "bash --login -c '$launch_cmd'" ``` ### Technical Analysis The working directory is derived from the third command-line argument, which the Skill instructions populate from a path supplied through a chat message. Although the script verifies that the path identifies an existing directory, it later interpolates that value into a shell command using manually constructed single quotes. A single quote inside the directory name can terminate the intended quoting context. Subsequent shell metacharacters in that directory name can then become executable shell syntax when the generated string is evaluated by `bash --login -c`. There are two nested levels of shell command interpretation: 1. `launch_cmd` embeds `workdir` and `CLAUDE_BIN` in a command string. 2. That command string is embedded again in the argument passed to `bash --login -c`. The directory existence check does not prevent exploitation because Unix file names may legally contain qu ...[truncated 2019 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Avoid composing shell source code from input values. 1. Use tmux's working-directory option to pass the directory as a distinct argument rather than embedding it in `cd`: ```bash tmux new-session -d \ -s "$TMUX_NAME" \ -c "$workdir" \ -x 220 -y 50 \ "env -u CLAUDECODE -u CLAUDE_CODE TERM=xterm-256color \"$CLAUDE_BIN\"" ``` 2. Prefer launching a small fixed wrapper script when tmux requires a command string. Pass the working directory and executable as positional arguments to the wrapper instead of interpolating them into shell code. 3. If string construction cannot be eliminated, apply shell-safe escaping to every interpolated value with `printf '%q'`. Escaping must account for both nested evaluation layers. 4. Resolve and validate the working directory with a canonicalization mechanism such as `realpath` where supported. 5. Validate that `CLAUDE_BIN` is an absolute path to an expected executable and reject unexpected values. 6. Add regression tests using valid directories containing single quotes, semicolons, spaces, dollar signs, and command-substitution characters. Confirm that no additional command is executed. ]]>
