Back to skill

Security audit

Tmux Manager

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real tmux manager, but its examples and implementation expose high-impact command execution and agent permission bypasses that users should review carefully before installing.

Install only if you are comfortable with a skill that can start, stop, and restart tmux sessions, run commands from YAML, and send commands into terminal panes. Review any tmux-sessions.yaml before use, avoid copying the sample AI-agent commands that skip approvals, prefer --dry-run and --list before kill or restart, and avoid using --tail on untrusted or oddly named tmux targets until the temp-file and pipe-pane handling is fixed.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/tmux-manager.py:458
Finding

Shell Command Injection Through the Tail Target

Content
View full analysis
> {log_file}"], check=True ) ``` ### Technical Analysis The `target` value originates from the user-controlled `-s SESSION[:WINDOW]` argument. Although the code verifies that the session portion exists, it does not validate the complete target or restrict characters in the window portion. The complete target is incorporated into `log_file`, which is then interpolated without shell quoting into the command supplied to `tmux pipe-pane`. The command passed to `pipe-pane` is interpreted by a shell. Consequently, shell metacharacters in a valid tmux window name, such as semicolons, redirection operators, command substitutions, or comment characters, can change the meaning of the command. Using a subprocess argument array only protects the outer invocation of `tmux`; it does not protect the nested command that tmux subsequently passes to a shell. ### Attack Path 1. The attacker creates, renames, or persuades the user to create a window in an existing tmux session with shell metacharacters in its name. 2. The attacker invokes or persuades the user to invoke: ```bash tmux-manager.py --tail -s 'work:x; touch PWNED; #' ``` 3. The session check validates only `work`, which is a legitimate running session. 4. The target-derived filename produces a nested shell command resembling: ```bash cat >> /tmp/tmux-tail-work-x; touch PWNED; #.log ``` 5. `tmux pipe-pane` executes the injected command in the securit ...[truncated 637 chars]
Remediation
View remediation
> {shlex.quote(log_file)}" subprocess.run(["tmux", "pipe-pane", "-t", target, pipe_command], check=True) ``` - Prefer a design that avoids a nested shell entirely, if supported by the tmux integration. - Resolve the supplied target through tmux and reject it if it does not exactly match an existing, expected session/window identifier. - Add regression tests using targets containing spaces, semicolons, command substitutions, redirection operators, quotes, and newline characters. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/tmux-manager.py:455
Finding

Predictable Temporary Log File Enables Symlink Attacks and Pane-Output Exposure

Content
View full analysis
> {log_file}"], check=True ) print(f"Tailing output from '{target}' (Ctrl+C to stop)\n{'-' * 50}") try: subprocess.run(["tail", "-f", log_file]) except KeyboardInterrupt: pass finally: # Stop piping subprocess.run(["tmux", "pipe-pane", "-t", target], check=False) try: os.unlink(log_file) except OSError: pass ``` ### Technical Analysis The tail log path is deterministic and stored in the system-wide temporary directory. It is not created atomically by the Python process, and the code performs no checks for pre-existing files, symbolic links, file ownership, or file type. The nested `cat >>` operation follows symbolic links. A local attacker who can write to the temporary directory can therefore create the expected path as a symbolic link before the victim starts tailing. Pane output will then be appended to the linked destination if the victim has permission to write to it. If a normal file is created under a permissive process umask, other local users may also be able to read pane output that can contain commands, tokens, paths, build logs, or other sensitive development information. The cleanup operation unlinks the pathname without verifying that it still identifies the file or ...[truncated 1419 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
README.md:34
Finding

Example Configuration Disables AI-Agent Permission Safeguards by Default

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/tmux-manager.py:3
Finding

Open-Ended Runtime Dependency Resolution Creates Supply-Chain Risk

Content
View full analysis
=3.10" # dependencies = [ # "pyyaml>=6.0", # ] # /// ``` ### Technical Analysis The project directs users to execute the script with `uv run`, while the inline dependency metadata accepts any PyYAML version at or above 6.0. No dependency lockfile or integrity hash is present in the audited project. As a result, executions performed at different times may resolve different package versions. A future compromised, malicious, or unexpectedly incompatible release satisfying the constraint could be installed and imported without review. Because dependency code executes inside the Python process, it receives the same filesystem, environment, and network access as the manager. No evidence was found that the current `pyyaml` package name is typosquatted or that a currently resolved release is malicious. The risk arises from unrestricted future resolution and lack of reproducibility. ### Attack Path 1. A user follows the documented command: ```bash uv run scripts/tmux-manager.py --all ``` 2. `uv` resolves the inline requirement `pyyaml>=6.0`. 3. A package version not previously reviewed by the project may satisfy the requirement and be downloaded. 4. The installed package is imported by: ```python import yaml ``` 5. Any malicious package initialization code would execute with the privileges and environment of the user running the manager. Successful exploitation requires compromise of the dependency distribution channel or publication of a harmful release that satisfies the declared constraint. ### Impact Assessment A compromised dependency could execute arbitrary Python code as the invoking user, read configuration and environment data, modify files, access user credentials, interfere with tmux sessions, or ...[truncated 123 chars]
Remediation
View remediation
", # ] ``` - Commit a dependency lockfile generated by the selected package-management workflow. - Use package hashes or integrity verification where supported. - Establish an explicit dependency-update process that includes vulnerability scanning, release-note review, and testing. - Configure package installation to use a trusted registry and avoid unapproved additional package indexes. - Periodically update the pin after reviewing newer releases rather than leaving resolution unconstrained. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (19)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
100% confidence
Finding

This is a classic tool-parameter abuse issue: untrusted configuration data is passed directly into subprocess.run(..., shell=True). In the skill context, that means a malicious or tampered session config can cause arbitrary shell execution on the host, potentially leading to data theft, persistence, or full system compromise.

Content

Scanner excerpt · scripts/tmux-manager.py (reported line 128)May include surrounding context.

python
def run_hook(hook_cmd, label):
    print(f"      [hook:{label}] {hook_cmd}")
    result = subprocess.run(hook_cmd, shell=True)
    if result.returncode != 0:
        print(f"      [!] {label} hook exited with code {result.returncode}")
    return result.returncode

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README explicitly documents destructive commands such as --all --kill and tmux kill-server without warning that they will terminate active tmux sessions and may abruptly stop long-running jobs, shells, or editors. In a skill whose purpose is to manage tmux sessions, users are likely to copy-paste these examples directly, so the lack of cautionary language materially increases the chance of accidental operational disruption.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill exposes shell-capable behavior and documents execution of a local Python wrapper around tmux, but it does not declare any explicit tool scope such as permissions or allowed-tools. That creates an authorization gap: an agent may invoke shell/MCP-capable actions more broadly than intended, including session creation, command injection into tmux panes, and execution of host-shell hooks defined in config.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/tmux-manager.py (reported line 101)May include surrounding context.

python
def run(cmd, check=True):
    return subprocess.run(cmd, check=check)


def session_exists(name):

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/tmux-manager.py (reported line 105)May include surrounding context.

python
def session_exists(name):
    result = subprocess.run(["tmux", "has-session", "-t", name],
                            capture_output=True, check=False)
    return result.returncode == 0

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill is explicitly designed to execute arbitrary shell content from configuration hooks and to send arbitrary commands into tmux panes/windows. In an agent-skill context, this materially expands capability from 'manage tmux sessions' to 'execute arbitrary host commands', making prompt/config abuse significantly more dangerous.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
99% confidence
Finding

run_hook executes config-supplied pre_hook and post_hook values with shell=True, allowing arbitrary shell command execution. Because the YAML config is an input to the skill, anyone who can influence that config can run commands on the host, which exceeds normal tmux session management and can lead to full local compromise.

Content

Scanner excerpt · scripts/tmux-manager.py (reported line 128)May include surrounding context.

python
def run_hook(hook_cmd, label):
    print(f"      [hook:{label}] {hook_cmd}")
    result = subprocess.run(hook_cmd, shell=True)
    if result.returncode != 0:
        print(f"      [!] {label} hook exited with code {result.returncode}")
    return result.returncode

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/tmux-manager.py (reported line 181)May include surrounding context.

python
# Apply session-level env vars
    for key, val in session_env.items():
        subprocess.run(["tmux", "setenv", "-t", name, key, str(val)], check=True)

    # Handle first window panes or command
    _setup_window(name, first_win_name, first_win, session_dir)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/tmux-manager.py (reported line 196)May include surrounding context.

python
# Focus a specific window if requested
    if focus:
        subprocess.run(["tmux", "select-window", "-t", f"{name}:{focus}"], check=False)

    # Post-hook
    if post_hook:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/tmux-manager.py (reported line 417)May include surrounding context.

python
def restart_sessions(sessions, config_path, dry_run=False):
    print(f"Config: {config_path}\n")
    if not dry_run:
        subprocess.run(["tmux", "start-server"], check=True)
    for session_cfg in sessions:
        name = session_cfg.get("name")
        if not name:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/tmux-manager.py (reported line 636)May include surrounding context.

python
def restart_sessions(sessions, config_path, dry_run=False):
    print(f"Config: {config_path}\n")
    if not dry_run:
        subprocess.run(["tmux", "start-server"], check=True)
    for session_cfg in sessions:
        name = session_cfg.get("name")
        if not name:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/tmux-manager.py (reported line 426)May include surrounding context.

python
print(f"  [dry] would kill and recreate: {name}")
        else:
            if session_exists(name):
                subprocess.run(["tmux", "kill-session", "-t", name], check=True)
                print(f"  [-] {name} (killed)")
            create_session(name, session_cfg, dry_run=False)
    print(f"\nDone: {len(sessions)} restarted.")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/tmux-manager.py (reported line 444)May include surrounding context.

python
print(f"  [dry] would kill and recreate: {name}")
        else:
            if session_exists(name):
                subprocess.run(["tmux", "kill-session", "-t", name], check=True)
                print(f"  [-] {name} (killed)")
            create_session(name, session_cfg, dry_run=False)
    print(f"\nDone: {len(sessions)} restarted.")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
87% confidence
Finding

This uses tmux pipe-pane with a command string containing a path derived from the target value. Since tmux executes the pipe command through a shell, an attacker controlling the session/window target could potentially inject shell metacharacters via the log filename construction, resulting in command execution.

Content

Scanner excerpt · scripts/tmux-manager.py (reported line 465)May include surrounding context.

python
log_file = os.path.join(tempfile.gettempdir(), f"tmux-tail-{target.replace(':', '-')}.log")

    # Start piping pane output to log file
    subprocess.run(
        ["tmux", "pipe-pane", "-t", target, f"cat >> {log_file}"],
        check=True
    )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/tmux-manager.py (reported line 472)May include surrounding context.

python
print(f"Tailing output from '{target}'  (Ctrl+C to stop)\n{'-' * 50}")

    try:
        subprocess.run(["tail", "-f", log_file])
    except KeyboardInterrupt:
        pass
    finally:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/tmux-manager.py (reported line 477)May include surrounding context.

python
pass
    finally:
        # Stop piping
        subprocess.run(["tmux", "pipe-pane", "-t", target], check=False)
        try:
            os.unlink(log_file)
        except OSError:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This manifest describes actions like creating, killing, restarting sessions, sending commands, and running hooks, which can affect running terminal workloads and session state. The text does not include any user-facing warning about possible disruption, command execution, or impact on active sessions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

This markdown file documents --kill and --restart, which can terminate tmux sessions and disrupt or discard active interactive work, but it does not explicitly warn users about that impact. Although the commands are named clearly, the skill description lacks a user-facing caution about killing active sessions or processes.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

For a skill framed as tmux session management, the validator and lister inspect arbitrary working_dir paths on the local filesystem and print resolved directories. While local path handling is connected to tmux setup, enumerating and disclosing filesystem existence/status is an additional capability not stated in the manifest description.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.