T09 · Insecure Skill Coding Practices
Error
- Location
- handler.js:10
- Finding
- Host Shell Command Injection Through Unsafe Command Interpolation## Vulnerability Details **File Location**: `handler.js`, lines 10-13 **Vulnerability Type**: OS command injection **Risk Level**: High ### 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 string passed to `execSync`. By default, `execSync` executes string commands through a system shell. Escaping only double quotation marks does not prevent shell evaluation inside double-quoted strings. Shell command substitutions using `$(...)` or backticks remain active and are evaluated by the host shell before `tmux` is invoked. Crafted backslash and quotation-mark sequences may also interfere with the intended quoting. This behavior violates the documented guarantee that commands are run inside the dedicated `claw` tmux session. Injected command substitutions execute directly in the environment of the Node.js skill process rather than in the tmux session. ### Attack Path 1. An attacker supplies a command containing shell substitution, for example: ```sh echo "$(touch /tmp/claw-shell-injected)" ``` 2. The value does not contain any substring rejected by `isDangerous`. 3. `sendCommand` escapes double quotation marks but leaves `$()` active. 4. The resulting command is passed to the host shell by `execSync`. 5. The host shell executes `touch /tmp/claw-shell-injected` before invoking `tmux`. 6. More consequential commands can be substituted to read, alter, or destroy resources available to the skill process. ### Impact Assessment An attacker able to control the `command` input can execute arbitrary operating-system commands with the user identity and privileges of the Node.js process. This can provide access to all files, credentials, environment variables, processes, and network resources available to that accou ...[truncated 273 chars]
- Remediation
- ## Remediation Suggestions Do not construct a shell command by interpolating untrusted text. Invoke `tmux` directly with a fixed executable and an argument array while disabling shell processing. For example: ```js const { execFileSync } = require("node:child_process"); function sendCommand(cmd) { execFileSync( "tmux", ["send-keys", "-t", "claw", "--", cmd, "C-m"], { shell: false, stdio: "ignore" } ); } ``` Additional hardening should include: 1. Reject NUL bytes and unexpected control characters in `cmd`. 2. Use fixed argument arrays for every `tmux` invocation, including session creation and output capture. 3. Run the skill under a dedicated, unprivileged operating-system account. 4. Restrict that account's filesystem and network access using sandboxing or container controls. 5. Add regression tests containing `$()`, backticks, nested quotes, backslashes, semicolons, and newlines, verifying that no command is evaluated by the host shell.
