Dispatch (Claude Code)

Security checks across malware telemetry and agentic risk

Overview

This skill mostly launches background Claude Code tasks as described, but it needs Review because it can switch into interactive tmux control and automatically approve security prompts in some modes.

Install only if you are comfortable with a skill that can run Claude Code against local repositories in the background and, for some prompts, in detached interactive tmux sessions. Avoid bypassPermissions, restrict project names to known safe repository slugs, keep result and log directories private, avoid putting secrets in prompts, and check for remaining nohup or tmux Claude sessions after use.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (14)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
claude_parts += args.extra

    launch = f"cd {shlex.quote(cwd)} && " + " ".join(shlex.quote(p) for p in claude_parts)
    subprocess.check_call(tmux_cmd(socket_path, "send-keys", "-t", target, "-l", "--", launch))
    subprocess.check_call(tmux_cmd(socket_path, "send-keys", "-t", target, "Enter"))

    # Workspace trust prompt (first run in a new folder).
Confidence
96% confidence
Finding
subprocess.check_call(tmux_cmd(socket_path, "send-keys", "-t", target, "-l", "--", launch))

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# Workspace trust prompt (first run in a new folder).
    if tmux_wait_for_text(socket_path, target, "Yes, I trust this folder", timeout_s=20):
        subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "Enter"), check=False)
        time.sleep(0.8)
        if tmux_wait_for_text(socket_path, target, "Yes, I trust this folder", timeout_s=2):
            subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "1"), check=False)
Confidence
99% confidence
Finding
subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "Enter"), check=False)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# If we send task text before accepting this prompt, it can accidentally choose the default "No, exit".
    if tmux_wait_for_text(socket_path, target, "Yes, I accept", timeout_s=10):
        # Select option 2 and confirm.
        subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "2"), check=False)
        subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "Enter"), check=False)
        time.sleep(0.8)
Confidence
99% confidence
Finding
subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "2"), check=False)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "Enter"), check=False)
        time.sleep(0.8)
        if tmux_wait_for_text(socket_path, target, "Yes, I trust this folder", timeout_s=2):
            subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "1"), check=False)
            subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "Enter"), check=False)

    # Bypass Permissions warning prompt (when running with --permission-mode bypassPermissions).
Confidence
97% confidence
Finding
subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "1"), check=False)

Tainted flow: 'socket_path' from os.environ.get (line 187, credential/environment) → subprocess.check_call (code execution)

Medium
Category
Data Flow
Content
claude_parts += args.extra

    launch = f"cd {shlex.quote(cwd)} && " + " ".join(shlex.quote(p) for p in claude_parts)
    subprocess.check_call(tmux_cmd(socket_path, "send-keys", "-t", target, "-l", "--", launch))
    subprocess.check_call(tmux_cmd(socket_path, "send-keys", "-t", target, "Enter"))

    # Workspace trust prompt (first run in a new folder).
Confidence
95% confidence
Finding
subprocess.check_call(tmux_cmd(socket_path, "send-keys", "-t", target, "-l", "--", launch))

Tainted flow: 'socket_path' from os.environ.get (line 187, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Content
# Workspace trust prompt (first run in a new folder).
    if tmux_wait_for_text(socket_path, target, "Yes, I trust this folder", timeout_s=20):
        subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "Enter"), check=False)
        time.sleep(0.8)
        if tmux_wait_for_text(socket_path, target, "Yes, I trust this folder", timeout_s=2):
            subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "1"), check=False)
Confidence
96% confidence
Finding
subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "Enter"), check=False)

Tainted flow: 'socket_path' from os.environ.get (line 187, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Content
# If we send task text before accepting this prompt, it can accidentally choose the default "No, exit".
    if tmux_wait_for_text(socket_path, target, "Yes, I accept", timeout_s=10):
        # Select option 2 and confirm.
        subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "2"), check=False)
        subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "Enter"), check=False)
        time.sleep(0.8)
Confidence
97% confidence
Finding
subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "2"), check=False)

Tainted flow: 'socket_path' from os.environ.get (line 187, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Content
subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "Enter"), check=False)
        time.sleep(0.8)
        if tmux_wait_for_text(socket_path, target, "Yes, I trust this folder", timeout_s=2):
            subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "1"), check=False)
            subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "Enter"), check=False)

    # Bypass Permissions warning prompt (when running with --permission-mode bypassPermissions).
Confidence
95% confidence
Finding
subprocess.run(tmux_cmd(socket_path, "send-keys", "-t", target, "1"), check=False)

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill exposes shell and environment access but does not declare permissions, which weakens reviewability and allows operators to underestimate what the skill can do. In this context, the skill launches background processes and consumes environment-derived paths/configuration, so missing permission declarations materially increase the chance of unsafe deployment or abuse.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The documented behavior presents a narrow, local, non-blocking dispatcher, but the broader described capabilities include interactive tmux execution, callback auto-configuration, external messaging integration, and multi-agent orchestration. That mismatch is dangerous because users and reviewers may authorize the skill for a limited use case while it actually enables expanded execution and data-routing paths, including potential exfiltration through callbacks or unintended command execution modes.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The file advertises and implements behavior broader than the skill's stated purpose, including interactive tmux orchestration and agent-team execution. Scope expansion matters in security review because extra execution modes introduce additional control channels, prompt automation, and subprocess surfaces that users of a 'headless dispatch' skill would not reasonably expect.

Context-Inappropriate Capability

Medium
Confidence
99% confidence
Finding
Interactive tmux orchestration includes pane capture, keystroke injection, and automated responses to trust/permission prompts, all of which materially increase the skill's power beyond simple async headless dispatch. In this context, that extra capability is dangerous because it lets the wrapper drive interactive security decisions and execute commands in a shell-backed session.

Missing User Warnings

Medium
Confidence
100% confidence
Finding
The wrapper automatically answers Claude Code security prompts for workspace trust and bypassPermissions acceptance. This defeats interactive safeguards designed to ensure a human explicitly consents before trusting a repository or enabling a highly permissive execution mode, which is especially risky in an asynchronous dispatch skill operating on user-specified workspaces.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The script persists the full task prompt, callback session key, Telegram routing identifiers, and working directory into a predictable results directory on disk. Prompts often contain sensitive source code, secrets, incident details, or internal instructions, and storing callback/session metadata alongside them increases the blast radius if the host is shared, backed up, or later accessed by another user or process.

VirusTotal

66/66 vendors flagged this skill as clean.

View on VirusTotal