Back to skill

Security audit

Browser Zombie Cleaner.Removed

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent cleanup purpose, but its kill mode can terminate more processes than its documentation promises.

Review this skill before installing or running it automatically. Use detect-only mode first, inspect the listed PIDs, avoid broad or empty --pattern values, and do not run --kill from a privileged health-check account unless the process-group targeting and log path are hardened.

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/cleanup-zombie-browsers.sh:343
Finding
Unverified Process-Group Termination Can Kill Unrelated Processes<![CDATA[ ## Vulnerability Details **File Location**: `scripts/cleanup-zombie-browsers.sh`, lines 343–365 **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: High ### Vulnerable Code ```bash # SIGTERM the process group (kills main + all children) log "Sending SIGTERM to PID $pid (+ ~$child_count child processes)" kill -TERM -- "-$(ps -o pgid= -p "$pid" 2>/dev/null | tr -d ' ')" 2>/dev/null \ || kill -TERM "$pid" 2>/dev/null \ || { log "PID $pid already gone"; continue; } # Wait for graceful exit waited=0 while (( waited < GRACE_PERIOD_SECONDS )); do if ! kill -0 "$pid" 2>/dev/null; then log "PID $pid and children terminated gracefully" break fi sleep 1 waited=$((waited + 1)) done # SIGKILL if still alive if kill -0 "$pid" 2>/dev/null; then log "PID $pid did not exit after ${GRACE_PERIOD_SECONDS}s, sending SIGKILL" kill -KILL -- "-$(ps -o pgid= -p "$pid" 2>/dev/null | tr -d ' ')" 2>/dev/null \ || kill -KILL "$pid" 2>/dev/null || true fi ``` ### Technical Analysis A negative PID passed to `kill` addresses an entire process group rather than only the validated browser PID. The discovery logic validates one process as a current-user, orphaned OpenClaw browser, but the script does not enumerate or validate every member of that process group before sending SIGTERM or SIGKILL. Process-group membership does not guarantee that every member is a descendant of the selected browser or that every member satisfies the OpenClaw command-line, ownership, orphan-status, and age checks. Consequently, the destructive operation has a broader scope than the documented browser-only safety boundary. The `child_count` calculation does not mitigate this issue. It only counts direct children and is not used to constrain which processes receive the signal. ### Attack Path 1. A qualifying browser process is placed in, or remains part of, a process group that also contains unrelated processes. 2. The ...[truncated 1025 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not signal the entire process group based on validation of a single PID. 2. Signal only the validated PID and explicitly enumerated descendants. 3. Before signaling each descendant, verify: - The process is owned by the expected UID. - Its ancestry leads to the originally selected browser. - Its process start time matches the recorded value, preventing PID-reuse errors. 4. Immediately revalidate the root process before each destructive action. 5. If process-group signaling is operationally required, enumerate every group member and abort unless every member passes the intended safety policy. 6. Record which exact PIDs were validated and signaled rather than estimating the number of affected children. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/cleanup-zombie-browsers.sh:329
Finding
Configurable Browser Pattern Weakens Target Selection and Kill-Time Revalidation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/cleanup-zombie-browsers.sh`, lines 42, 148, and 329–333 **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: Medium ### Vulnerable Code ```bash --pattern) OPENCLAW_BROWSER_PATTERN="$2"; shift 2 ;; ``` ```bash # Must have OpenClaw browser pattern in cmdline [[ "$cmdline" == *"$OPENCLAW_BROWSER_PATTERN"* ]] || continue ``` ```bash # Verify process still exists and still matches criteria before killing if [[ "$OS" == "linux" ]] && [[ -d "/proc/$pid" ]]; then verify_cmdline="$(tr '\0' ' ' < "/proc/$pid/cmdline" 2>/dev/null)" || continue if [[ "$verify_cmdline" != *"$OPENCLAW_BROWSER_PATTERN"* ]]; then log "SKIP PID $pid: re-verification failed (cmdline changed)" continue fi fi ``` ### Technical Analysis The `--pattern` option accepts an arbitrary string without validating that it is nonempty, sufficiently specific, or tied to the expected OpenClaw browser directory. An empty pattern matches every command line under Bash wildcard comparison, while a broad pattern can match browser processes unrelated to OpenClaw. The kill-time check is also incomplete. Although its comment states that the process still matches the criteria, it only verifies that the command line contains the configurable pattern. It does not repeat the following safety checks: - Current-user ownership - Browser executable identity - Orphan status - Minimum process age - Process start time or another PID-reuse-resistant identifier The gap between discovery and signaling therefore creates a time-of-check/time-of-use weakness. A candidate may no longer meet the original policy when the signal is sent. ### Attack Path 1. The caller supplies an empty or overly broad value through `--pattern`. 2. The command-line origin check begins accepting browser processes that were not launched with the intended OpenClaw browser directory. 3. An accepted process also satisfies the orphan a ...[truncated 927 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--pattern` unless overriding the OpenClaw path is essential. 2. If it must remain available: - Reject empty values. - Require a canonical absolute path under the expected OpenClaw browser directory. - Reject overly short or generic values. - Compare against the parsed browser profile argument rather than performing an unrestricted substring match. 3. Record the process UID, executable identity, parent PID, and start time during discovery. 4. Immediately before signaling, revalidate: - UID and ownership - Exact executable or trusted executable path - Exact OpenClaw user-data directory - Current orphan status - Current age - Original start time 5. Skip the process if any property differs from the discovery record. 6. Prefer PID handles or platform facilities resistant to PID reuse where available. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/cleanup-zombie-browsers.sh:31
Finding
Predictable Log Path Permits Symlink-Based File Modification<![CDATA[ ## Vulnerability Details **File Location**: `scripts/cleanup-zombie-browsers.sh`, lines 31, 70, and 75 **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: Medium ### Vulnerable Code ```bash LOG_FILE="${OPENCLAW_ZOMBIE_LOG:-/tmp/openclaw/zombie-browser-cleanup.log}" ``` ```bash mkdir -p "$(dirname "$LOG_FILE")" ``` ```bash log() { local msg="[$(date '+%Y-%m-%d %H:%M:%S')] $*" echo "$msg" >> "$LOG_FILE" if [[ "$OUTPUT_FORMAT" == "text" ]]; then echo "$msg" fi } ``` ### Technical Analysis The default log is placed under a predictable `/tmp` path. The script creates the parent directory without setting restrictive permissions and opens the log with shell append redirection without validating: - Whether the parent directory is owned by the invoking user - Whether the log path is a symbolic link - Whether the destination is a regular file - Whether an existing file is owned by the expected user - Whether the path changed between validation and opening The path can also be overridden through the environment or command-line option. Although configurable logging is intentional, unrestricted append operations become dangerous when the script is used by an automated or privileged account. Standard shell redirection follows symbolic links. Therefore, an attacker able to control the predictable temporary path may redirect log writes to another file writable by the invoking account. ### Attack Path 1. An attacker creates or controls `/tmp/openclaw` before the cleanup script runs, or otherwise gains write access to the configured log directory. 2. The attacker creates `zombie-browser-cleanup.log` as a symbolic link to another file. 3. A more privileged or different automation account invokes the script using the predictable default path. 4. The shell follows the symbolic link when executing `echo "$msg" >> "$LOG_FILE"`. 5. Audit text is appended to the symlink target under the invoking account's permission ...[truncated 652 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store logs in a private runtime or state directory owned by the invoking user rather than a shared predictable `/tmp` path. 2. Create the directory with mode `0700` and verify its owner before use. 3. Refuse to write if the destination is a symbolic link, non-regular file, or owned by another account. 4. Create new log files with restrictive permissions such as `0600`. 5. Use a logging implementation that supports atomic creation and no-follow semantics, such as opening the file with `O_NOFOLLOW` and validating it with `fstat`. 6. If shell-only portability is required, use a securely created private directory, verify it has not been replaced, and avoid privileged execution. 7. Validate command-line and environment-provided log paths against an approved directory policy. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Vague Triggers

Medium
Confidence
91% confidence
Finding
This manifest is a markdown file with frontmatter, so vague-trigger review applies. The trigger "chrome memory" is short and generic enough to match common user speech about browser performance, without clearly limiting activation to OpenClaw orphan-process cleanup.

Vague Triggers

Medium
Confidence
94% confidence
Finding
"Browser cleanup" could refer to many unrelated tasks such as clearing cache, cookies, tabs, or uninstalling browsers. The file does not pair the trigger list with exclusion conditions or negative examples, so this phrase risks unintended invocation outside the intended orphaned-process use case.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
The script advertises that it only targets specific orphaned OpenClaw browser processes, but in kill mode it re-verifies only the OpenClaw path substring and then sends signals to the entire process group. If an unrelated process shares that process group, it may be terminated even though it was never validated as a browser, orphan, same-age candidate, or intended cleanup target. In an operational cleanup skill, that mismatch between documented scope and actual kill behavior makes accidental denial-of-service plausible.

Natural-Language Policy Violations

Low
Confidence
76% confidence
Finding
Natural-language policy review applies to all file types. The manifest mixes English and Chinese triggers, but does not explain whether multilingual activation is optional or how language selection is determined, creating a mild locale-policy concern around implicit language handling.

Static analysis

No suspicious patterns detected.