T09 · Insecure Skill Coding Practices
Error
- Location
- handler.js:10
- Finding
- Host Shell Command Injection Through Unsafe tmux Invocation<![CDATA[ ## Vulnerability Details **File Location**: `handler.js`, lines 10–12 **Vulnerability Type**: OS command injection **Risk Level**: Critical ### Vulnerable Code ```js function sendCommand(cmd) { const escaped = cmd.replace(/"/g, '\\"'); execSync(`tmux send-keys -t claw "${escaped}" C-m`); } ``` ### Technical Analysis The attacker-controlled `cmd` value is interpolated into a command executed by `execSync`. The code only escapes double quotation marks, which does not prevent shell evaluation inside a double-quoted argument. Shell constructs such as command substitutions using `$()` or backticks are evaluated by the host shell before `tmux send-keys` runs. Consequently, a command intended merely to be typed into tmux can cause a separate command to execute directly in the Node.js process environment. For example, an input containing: ```sh echo "$(id > /tmp/claw-proof)" ``` causes the host shell to execute `id > /tmp/claw-proof` while preparing the arguments for `tmux`. This execution occurs outside the documented tmux session boundary. ### Attack Path 1. An attacker supplies a crafted `command` value to `claw_shell_run`. 2. The basic dangerous-command filter does not reject shell substitutions. 3. `sendCommand` escapes only literal double quotes. 4. The resulting string is passed to `execSync`, which invokes a host shell. 5. The host shell evaluates `$()` or backtick substitutions before launching tmux. 6. The substituted command executes directly with the privileges of the Node.js Skill process. 7. Its output is then embedded in the text sent to tmux, potentially concealing the separate host-side execution. ### Impact Assessment Successful exploitation permits arbitrary command execution with the operating-system privileges of the Skill process. An attacker may read or modify files accessible to that account, access environment variables and credentials, launch processes, modify the project workspace, or interact with other local resou ...[truncated 279 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Avoid constructing shell command strings from user input. Invoke tmux directly with an argument array and disable shell interpretation: ```js const { spawnSync } = require("node:child_process"); function sendCommand(cmd) { const result = spawnSync( "tmux", ["send-keys", "-t", "claw", "--", cmd, "C-m"], { shell: false, encoding: "utf8" } ); if (result.error) { throw result.error; } if (result.status !== 0) { throw new Error(result.stderr || "tmux send-keys failed"); } } ``` Confirm the exact `tmux send-keys` argument semantics for the deployed tmux version and use an end-of-options marker where supported. Do not attempt to make shell interpolation safe through manual character escaping. Additional hardening should include: - Run the Skill under a dedicated, least-privileged account. - Apply filesystem and process isolation appropriate for arbitrary shell execution. - Set explicit execution timeouts and output limits. - Validate that the selected tmux target is exactly the intended session and pane. - Add regression tests using `$()`, backticks, quotes, newlines, semicolons, and other shell metacharacters. ]]>
