Back to skill

Security audit

Claude Code Supervisor

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real Claude Code session supervisor, but it installs automatic hooks that can run project-configured commands and forward terminal/session content to LLM or notification backends.

Review before installing. Use this only in repositories and environments you trust, inspect any existing .claude-code-supervisor.yml before enabling hooks, avoid arbitrary notify.command or triage.command values, and do not send notifications to external services unless you are comfortable sharing paths, prompts, error output, and task context. Run the watchdog as a normal user, avoid fixed /tmp helpers where possible, and require human approval for permission prompts or destructive actions.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/lib.sh:45
Finding

Project-Local Configuration Can Execute Attacker-Selected Commands

Content
View full analysis
/dev/null || true } # Run LLM triage via configured command. ccs_triage() { local config_file="$1" local prompt="$2" local triage_cmd model max_tokens triage_cmd=$(ccs_config_get "$config_file" "triage.command" "claude -p --no-session-persistence") model=$(ccs_config_get "$config_file" "triage.model" "claude-haiku-4-20250414") max_tokens=$(ccs_config_get "$config_file" "triage.max_tokens" "150") echo "$prompt" | $triage_cmd --model "$model" --max-tokens "$max_tokens" 2>/dev/null } ``` The installer explicitly preserves an existing project configuration: ```bash if [ ! -f "$PROJECT_DIR/.claude-code-supervisor.yml" ]; then cp "$REPO_DIR/supervisor.yml.example" "$PROJECT_DIR/.claude-code-supervisor.yml" echo " ✓ Created .claude-code-supervisor.yml (edit to configure)" else echo " · .claude-code-supervisor.yml already exists, skipping" fi ``` ### Technical Analysis The project- ...[truncated 1913 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/lib.sh:74
Finding

Predictable Files in Shared Temporary Storage Permit Symlink Clobbering

Content
View full analysis
"$script_path" <
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/triage.sh:22
Finding

Untrusted Terminal and Event Content Can Manipulate LLM Triage Decisions

Content
View full analysis
/dev/null || echo "unknown") fi PROMPT="You are a coding agent supervisor. A Claude Code session just triggered an event. Event: ${EVENT_TYPE} Project: ${CWD} Goal: ${GOAL} Recent terminal output: ${CONTEXT} Classify this situation with exactly one word on the first line: FINE - Agent is working normally, no intervention needed NEEDS_NUDGE - Agent hit a transient error or stopped prematurely, should be told to continue STUCK - Agent is looping or not making progress, needs different approach DONE - Agent completed the task successfully ESCALATE - Situation needs human judgment Then a one-line explanation." VERDICT=$(ccs_triage "$CONFIG" "$PROMPT") ``` For example, the stop hook captures terminal output directly: ```bash PANE_OUTPUT=$(tmux -S "$SOCKET" capture-pane -p -J -t "$TMUX_SESSION" -S -30 2>/dev/null || echo "") if echo "$PANE_OUTPUT" | tail -10 | grep -qiE "API Error: 5[0-9][0-9]|internal.server.error|api_error"; then "$SUPERVISOR_DIR/triage.sh" "stopped:api_error" "$CWD" "$PANE_OUTPUT" & exit 0 fi ``` ### Technical Analysis Terminal output, tool errors, notification messages, and the stored goal are inserted into the same natural-language prompt as the classifier instructions. The prompt does not clearly delimit these fields as untrusted data or te ...[truncated 1677 chars]
Remediation
View remediation
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
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description emphasizes hook-based supervision and LLM triage, but the documented behavior also includes periodic watchdog execution and active tmux intervention via send-keys. That mismatch is dangerous because users may consent to passive monitoring while overlooking independent scheduled execution and command injection into active sessions, both of which materially expand the skill's authority and attack surface.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scripts/watchdog.sh (reported line 98)May include surrounding context.

sh
fi
        else
          # Not idle — clear marker
          rm -f "/tmp/ccs-idle-${SESSION_NAME}"
        fi
      fi
    fi

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README explicitly encourages sending supervision events to external commands such as webhooks, ntfy, Slack, or custom scripts, and states the notifier receives a JSON payload, but it does not warn users that session metadata and possibly terminal/error content may leave the local machine. In the context of a tool supervising coding-agent sessions, those payloads can plausibly contain prompts, file paths, error messages, secrets, or proprietary code context, creating an avoidable data disclosure risk through misconfiguration or over-sharing.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill clearly instructs users to run shell commands, install hook scripts, create state files, and operate tmux sessions, but it does not declare an explicit tool scope such as permissions or allowed-tools. That omission weakens the trust boundary for an automation skill with shell-side effects, making it easier for a caller to invoke filesystem and process-manipulating behavior without clear prior disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill directs installation of hooks into a project and creation of configuration/state files, but it does not prominently warn that local project and user files will be modified. Silent or under-disclosed modification of hook/config files can persist behavior across future sessions and may surprise users, especially when the changes affect lifecycle execution.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
82% confidence
Finding

The skill stores persistent session metadata in a home-directory JSON file, including project paths, goals, success criteria, socket paths, and runtime status. This creates a durable record of potentially sensitive operational context that could be exposed to other local users, backup systems, or later processes if not permission-restricted and lifecycle-managed.

Content

Scanner excerpt · SKILL.md (reported line 76)May include surrounding context.

3. Register a supervised session

Create ~/.openclaw/workspace/supervisor-state.json (or wherever your harness keeps state):

json
{

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs the supervisor to automatically answer permission prompts with "y" when it subjectively appears to be within safety bounds, but it provides no robust verification mechanism, explicit allowlist, or user confirmation step. In a tmux-supervised coding session, this can authorize file modifications, command execution, network access, or other sensitive actions that the underlying agent requested, effectively bypassing an important safety checkpoint.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/hooks/on-notify.sh (reported line 29)May include surrounding context.

sh
exit 0
    ;;
  permission_prompt)
    # Agent needs permission — might be able to auto-approve, or escalate
    "$SUPERVISOR_DIR/triage.sh" "notification:permission" "$CWD" \
      "Permission requested: $MESSAGE | Session: $SESSION_ID" &
    ;;

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The hook forwards potentially sensitive runtime context (current working directory, session ID, and message content) into another processing script without any minimization, consent, or indication here of how that data will be handled. In a supervisor/notification skill, those fields may contain repository names, filesystem paths, prompts, or task details, so this creates a real data-exposure boundary that could leak information to downstream logging, LLM triage, or external notification backends.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This hook incorporates recent terminal output into a logging/triage workflow based on pattern matches, again without user-facing disclosure. In the context of a supervisor for long-running coding sessions, the monitored pane is especially likely to include proprietary code, credentials, error payloads, and operational details, so silent collection and downstream processing increases privacy and secret-leak risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script captures recent tmux pane contents and forwards the full output to a secondary triage script in the background. Terminal panes commonly contain sensitive data such as prompts, source code, secrets, file paths, and user input, so this creates a data-exposure channel without any visible notice, consent, minimization, or boundary on where triage.sh may send or store the content.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The library reads notify.command and triage.command from YAML and executes them as shell commands with untrusted data attached, turning a monitoring helper into a general command-execution mechanism. Because this skill is specifically designed to run unattended and process agent output, a malicious or tampered config can execute arbitrary programs and exfiltrate prompts, status text, or other sensitive session data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Notification commands from config are invoked with JSON payloads containing message text, and there is no user-facing disclosure here that status data may be transmitted to an arbitrary external command. In a supervisor for long-running coding sessions, these messages can include task summaries or other sensitive workflow details, creating a meaningful privacy and exfiltration risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

ccs_triage pipes the full prompt to a configurable external triage command without any warning or trust boundary enforcement. Since prompts may contain captured terminal output, errors, code, secrets, or project context, this can silently expose sensitive data to any configured tool or endpoint.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The generated helper script embeds the configured notification command directly into an executable file and later runs it with agent-supplied message content. This persists an arbitrary execution path to disk, broadens the blast radius beyond the current process, and makes any malicious config value easier to trigger repeatedly or by another component.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script embeds raw terminal output and other session context directly into an LLM prompt, then forwards the model’s full response in notifications. If the context contains secrets, credentials, proprietary code, or sensitive user data, the model may echo or summarize that material, causing data leakage to logs or notification backends.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script is not purely observational: it actively sends keystrokes into a live tmux session based on inferred idle state. That can alter the supervised agent’s behavior, trigger unintended actions, or inject unreviewed text into a sensitive workflow, especially if session state detection is inaccurate or the nudge message is configurable by another party.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The watchdog captures recent tmux pane contents and includes them in notifications, which can exfiltrate secrets, proprietary code, prompts, tokens, or user data from the supervised session. Because the notification backend is harness-agnostic and may forward to external systems, this creates a real confidentiality risk beyond local logging.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The introductory comments describe copying hook scripts, merging hook config into .claude/settings.json, and creating a config file if missing. The actual script also modifies or creates .claude/settings.json and generates /tmp/supervisor-notify.sh, so the comments understate additional side effects of the installer.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The script creates directories, copies multiple hook scripts, marks them executable, and creates a new project config file. Although it prints progress messages, it does not clearly warn the user beforehand that it will modify the target project's .claude directory and install automatically executing hooks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The script merges hook configuration into .claude/settings.json or creates that file if missing, which changes the project's Claude behavior. While success messages are printed after the fact, there is no prior disclosure that hook settings will be modified and persisted.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The installer generates an executable helper at a fixed global path (/tmp/supervisor-notify.sh), which is outside the project boundary and in a world-writable directory. Even though the script content is generated locally, using a predictable file in /tmp creates symlink/race and cross-user tampering risks, and can leave a reusable helper that other processes may invoke unintentionally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

Creating an executable wrapper in /tmp without clear notice is more than just a warning issue because it places a reusable executable in a shared temporary location. In this skill context, which supervises long-running agents and encourages automated invocation of helper scripts, that global helper is more likely to be reused, making path predictability and tampering concerns more relevant.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

ccs_generate_notify_script creates a shell script at a filesystem path and marks it executable, but this side effect is not disclosed through a prompt or user-facing log. File creation in /tmp is safety-relevant enough to merit explicit notice, especially because the generated script also executes a configured command.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.