Back to skill

Security audit

My Claw Shell

Security checks for vulnerabilities and agentic risk

Overview

This skill is a tmux shell runner, but it grants broad local command execution with safeguards that are incomplete and partly contradicted by the implementation.

Review before installing. Use this only if you intentionally want a broad local shell bridge, and run it in a disposable or least-privileged environment. Do not rely on its dangerous-command warning as a safety boundary, and treat commands as able to read, modify, or delete local data accessible to the skill process.

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 (2)

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. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
handler.js:22
Finding
Dangerous-Command Restrictions Can Be Bypassed<![CDATA[ ## Vulnerability Details **File Location**: `handler.js`, lines 22–42 **Vulnerability Type**: Insufficient command validation and authorization enforcement **Risk Level**: High ### Vulnerable Code ```js function isDangerous(cmd) { const bad = ["sudo", " rm ", " rm-", "reboot", "shutdown", "mkfs", "dd "]; const lower = ` ${cmd.toLowerCase()} `; return bad.some(k => lower.includes(k)); } // MAIN ENTRYPOINT // OpenClaw will call this function when using the skill tool async function claw_shell_run(input) { const { command } = input; if (!command || typeof command !== "string") { return { error: "command is required" }; } if (isDangerous(command)) { return { error: "dangerous_command", message: `Command looks dangerous. Ask the user for explicit approval before running: ${command}` }; } ``` ### Technical Analysis The safety control relies on matching a small list of literal substrings. This approach does not parse shell syntax and cannot reliably identify the executable or the operation that will ultimately run. For example, the documented restriction against `rm` may be bypassed by invoking it through a path: ```sh /bin/rm /tmp/target ``` The padded input contains `/bin/rm`, not the exact substring `" rm "`, so it can pass the filter. Equivalent operations may also be hidden behind shell functions, aliases, interpreters, scripts, variable expansion, command substitution, or utilities absent from the denylist. The implementation also lacks an approval token, approval state, or separate approved-execution path. A detected command is always rejected, while a disguised command can execute without approval. Therefore, the implementation does not enforce the documented requirement to request and then honor explicit user authorization. ### Attack Path 1. An attacker or untrusted instruction requests a destructive operation. 2. The operation is expressed without a listed literal substring, such as by using an ...[truncated 910 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Do not use a substring denylist as the primary security boundary for arbitrary shell commands. Recommended controls include: 1. Replace unrestricted shell access with narrowly scoped, structured operations whenever possible. 2. If command execution is required, use an allowlist of permitted executables and validate arguments separately. 3. Resolve executable paths and reject shell wrappers, interpreters, redirects, substitutions, pipelines, and compound expressions unless explicitly required. 4. Introduce a verifiable approval mechanism. A dangerous request should produce a pending operation identifier, and execution should require a separate, authenticated approval tied to the exact immutable command. 5. Invalidate approval whenever the command or arguments change. 6. Execute commands in a sandbox or container with least privilege, restricted filesystem access, resource limits, and no unnecessary credentials. 7. Log the submitted command, approval decision, resolved executable, execution identity, and result. 8. Add tests covering absolute and relative executable paths, shell expansion, aliases, scripts, interpreters, newlines, redirects, pipelines, and command chaining. Even with improved parsing, arbitrary shell commands cannot be comprehensively classified as safe by a finite denylist. Isolation and least privilege are required as defense-in-depth. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (2)

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The skill documents confirmation requirements for dangerous commands, but the skill still exposes a generic shell-execution interface that can run arbitrary commands in a persistent tmux session. Because the safety policy is only advisory text in the markdown and not an enforceable control, an agent or downstream implementation may execute destructive commands without prompting, leading to system damage, data loss, or privilege-impacting actions within the host environment.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
This code takes an arbitrary string from input.command and sends it into a persistent tmux shell session for execution, with no allowlist, sandboxing, or reliable user-confirmation control in the execution path. The only protection is a weak substring-based dangerous-command filter that is easy to bypass and does not prevent harmful shell behavior such as file exfiltration, destructive commands with altered spacing/encoding, command chaining, or other unsafe operations.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
handler.js:5