Back to skill

Security audit

Taizi Claw Shell

Security checks for vulnerabilities and agentic risk

Overview

This skill openly provides shell access, but its implementation can run user-supplied input through the host shell outside the stated tmux boundary and relies on weak safety controls.

Review carefully before installing. This skill gives broad shell authority and should only be used in a tightly sandboxed environment with no sensitive files, credentials, or network access. The handler should be changed to call `tmux` with argument arrays rather than a shell string and should add real user approval or stricter command policy before it is trusted.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
handler.js:12
Finding
Host-Shell Command Injection Through Unsafe tmux Command Construction## Vulnerability Details **File Location**: `handler.js`, lines 12–14 **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 `cmd` value is supplied by the caller and interpolated into a command string executed by `execSync()`. Node.js passes this string to a host shell. The implementation escapes only double-quote characters, which does not prevent shell evaluation of command substitutions such as `$()` or backticks. Consequently, a crafted value can cause the host shell to execute commands while constructing the arguments for `tmux`. This execution occurs outside the designated tmux session and therefore violates the documented isolation expectation that commands are run inside session `claw`. The `isDangerous()` substring denylist does not eliminate this vulnerability. It only detects a small set of literal strings and does not account for shell substitutions, alternate command syntax, variable expansion, encoding, or equivalent utilities. A payload containing a substitution that does not include one of the blocked substrings can reach `sendCommand()` and execute in the host shell. ### Attack Path 1. An attacker or untrusted caller invokes `claw_shell_run` with a crafted `command` containing shell substitution syntax, such as: ```sh echo $(touch /tmp/claw-shell-injection-proof) ``` 2. The command passes the denylist because it contains none of the listed blocked substrings. 3. `sendCommand()` escapes only double quotes and interpolates the remaining input into: ```sh tmux send-keys -t claw "echo $(touch /tmp/claw-shell-injection-proof)" C-m ``` 4. The host shell evaluates `$(touch /tmp/claw-shell-injection-proof)` before `tmux` receives its arguments. 5. The injected command executes direc ...[truncated 968 chars]
Remediation
## Remediation Suggestions Do not construct shell command strings with caller-controlled input. Invoke `tmux` directly with an argument array and disable shell interpretation. Send the command as literal text and submit Enter separately, for example: ```js const { execFileSync } = require("node:child_process"); function sendCommand(cmd) { execFileSync("tmux", ["send-keys", "-t", "claw", "-l", "--", cmd], { shell: false }); execFileSync("tmux", ["send-keys", "-t", "claw", "C-m"], { shell: false }); } ``` Additional hardening should include: 1. Avoid using shell-backed `execSync()` for all fixed tmux operations; use `execFileSync()` or `spawnSync()` with fixed executable names and argument arrays. 2. Treat substring denylisting as defense-in-depth only, not as an injection control. 3. Implement explicit authorization state if dangerous commands are intended to run after user approval. The current API has no approval field and therefore cannot securely distinguish an approved request from an unapproved one. 4. Apply an allowlist or a structured command policy if the tool does not require unrestricted shell access. 5. Run the skill under a dedicated, least-privileged operating-system account with restricted filesystem, credential, and network access. 6. Add regression tests using `$()`, backticks, quotes, newlines, semicolons, pipes, redirections, and variable expansion to verify that input reaches tmux literally and is never evaluated by the host shell.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (1)

Missing User Warnings

Medium
Confidence
98% confidence
Finding
This skill executes arbitrary user-supplied shell commands by forwarding them into a persistent tmux shell session, but it provides only a weak substring-based blocklist and no meaningful safety boundary or clear user-facing disclosure of the risks. The blocklist is trivially bypassed, the command is still interpreted by a shell-like environment inside tmux, and the persistent session increases the chance of unintended stateful or chained harmful actions.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
handler.js:5