Back to skill

Security audit

Gateway Watchdog

Security checks for vulnerabilities and agentic risk

Overview

This watchdog has a coherent monitoring purpose, but it can persist across sessions and automatically kill broadly matched local processes, which creates real operational risk.

Review carefully before installing. Use only a trusted, pinned revision, avoid running it as root/admin, disable DingTalk unless you accept status data going to that webhook, and do not enable autostart until process termination is narrowed to the exact Gateway process and Linux/macOS uninstall steps are provided.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
gateway_monitor.py:146
Finding

Overbroad Process Termination Can Disrupt Unrelated Applications

Content
View full analysis

Vulnerability Details

File Location: gateway_monitor.py:146-153
Vulnerability Type: Overbroad process termination
Risk Level: High

python
if system == "Windows":
    try:
        subprocess.run(["taskkill", "/F", "/IM", "node.exe"], 
                      capture_output=True, timeout=10)
    except Exception:
        pass
else:  # Linux/Mac
    try:
        # Kill all OpenClaw-related processes
        subprocess.run(["pkill", "-f", "openclaw"], 
                      capture_output=True, timeout=10)
    except Exception:
        pass

Technical Analysis

When the health check fails, the watchdog attempts to remove existing Gateway processes before restarting the service. The process selection is not sufficiently scoped:

  • On Windows, taskkill /F /IM node.exe forcibly terminates every process named node.exe, not only the OpenClaw Gateway.
  • On Linux and macOS, pkill -f openclaw terminates every process whose command line contains openclaw, including unrelated OpenClaw components.
  • The code does not validate a PID, executable path, process owner, listening port, or service identity before termination.
  • Exceptions and command output are discarded, preventing operators from identifying unintended termination or partial failures.

Because the watchdog is designed to run persistently, the destructive operation may be repeated whenever the health check continues to fail. A network error, incorrect GATEWAY_URL, authentication response, transient startup delay, or legitimate non-200 response can therefore trigger termination of unrelated processes.

Attack Path

  1. The watchdog starts and performs an HTTP request against the configured Gateway URL.
  2. The request fails or returns a status other than HTTP 200.
  3. The watchdog treats the result as a Gateway outage.
  4. On Windows, it invokes taskkill /F /IM node.exe; on Unix-like systems, it invokes `pkill -f opencla ...[truncated 1055 chars]
Remediation
View remediation

Remediation Suggestions

  1. Use the official OpenClaw service-management or scoped restart interface instead of generic process-name termination.
  2. Record the PID when starting the Gateway and store it in a user-owned PID file.
  3. Before terminating a recorded PID, verify:
    • The process belongs to the expected user.
    • Its executable path matches the expected OpenClaw executable.
    • Its command-line arguments identify the Gateway component.
    • It is associated with the configured Gateway port where applicable.
  4. On Windows, terminate the validated PID rather than all node.exe processes.
  5. On Linux and macOS, avoid pkill -f; use a validated PID or a dedicated service unit.
  6. Require multiple consecutive health-check failures before taking destructive action.
  7. Distinguish transport failure from application health failure and support an explicit health endpoint.
  8. Log termination targets, command results, and errors instead of silently suppressing them.
  9. Run the watchdog as a dedicated unprivileged account whose process-control permissions are limited to the Gateway.

T03 · Remote Payload Retrieval and Execution

Warning
Location
SKILL.md:22
Finding

Mutable Remote Repository Is Retrieved and Executed Without Integrity Pinning

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:22-38
Additional Location: README.md:28-56
Vulnerability Type: Unpinned remote payload retrieval and execution
Risk Level: Medium

bash
git clone https://github.com/adminlove520/gateway-watchdog.git
cd gateway-watchdog
bash
cp config.example.py config.py
# Edit config.py and enter the DingTalk webhook and signing secret
bash
python install.py
# Select "1" to install startup persistence

Technical Analysis

The Skill directs users or an agent to clone the current state of a remote Git repository and execute install.py. The instructions do not pin an audited commit hash or signed release and do not verify a cryptographic checksum or signature.

Consequently, the effective code executed during installation can change after the reviewed Skill package has been published. Compromise of the upstream account, repository, default branch, or release process could replace install.py, gateway_monitor.py, or the configuration template with attacker-controlled content.

This behavior is especially sensitive because the downloaded installer can:

  • Execute arbitrary Python code with the invoking user's permissions.
  • Create startup persistence.
  • Direct users to perform system-level service installation.
  • Read a local config.py containing a DingTalk webhook token and signing secret.

The repository URL itself is visible and the retrieval is documented, so this is not a concealed payload. The risk arises from executing mutable remote content without binding installation to the audited revision.

Attack Path

  1. An attacker compromises the upstream GitHub account, repository, default branch, or a maintainer's credentials.
  2. The attacker modifies install.py, gateway_monitor.py, or another imported file.
  3. A user follows the Skill instructions and clones the repository without selecting a fixed revision.

...[truncated 903 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin installation to a specific audited commit hash or immutable signed release tag.
  2. Publish a SHA-256 digest for the approved source archive and verify it before execution.
  3. Use signed releases or Git commit-signature verification and fail closed if verification fails.
  4. Display and verify the checked-out commit before running any Python script.
  5. Avoid recommending execution directly from the mutable default branch.
  6. Vendor the reviewed installer into the Skill package when feasible.
  7. Separate unprivileged installation from privileged service registration.
  8. Require users to inspect and explicitly approve generated system service definitions before privileged installation.
  9. Document the trusted publisher identity, expected repository revision, and verification procedure.

T06 · System Persistence

Warning
Location
install.py:161
Finding

Linux and macOS Persistence Cannot Be Removed by the Advertised Uninstall Function

Content
View full analysis

Vulnerability Details

File Location: install.py:161-194
Related Persistence Locations: install.py:70-146
Vulnerability Type: Incomplete removal of startup persistence
Risk Level: Medium

python
if len(sys.argv) > 1:
    command = sys.argv[1].lower()
    
    if command in ["uninstall", "remove", "delete"]:
        system = platform.system()
        if system == "Windows":
            uninstall_windows()
        else:
            print("❌ Only Windows uninstall is supported")
        return

system = platform.system()
print(f"\nDetected system: {system}")
print()

print("1. Install startup persistence")
print("2. Uninstall startup persistence")
print("3. Run directly for testing")
print("4. View status")
print("0. Exit")
print()

choice = input("Select [1-4, 0]: ").strip()

if choice == "1":
    if system == "Windows":
        install_windows()
    elif system == "Linux":
        install_linux()
    elif system == "Darwin":
        install_macos()
    else:
        print(f"❌ Unsupported system: {system}")
elif choice == "2":
    if system == "Windows":
        uninstall_windows()
    else:
        print("❌ Only Windows uninstall is supported")

The corresponding persistence setup includes a systemd service for Linux and a LaunchAgent for macOS:

python
service_file = f"/etc/systemd/system/{service_name}.service"
...
print(f"  sudo systemctl enable {service_name}")
print(f"  sudo systemctl start {service_name}")
python
plist_path = os.path.expanduser(f"~/Library/LaunchAgents/{plist_name}")
...
with open(plist_path, "w") as f:
    f.write(plist_content)
...
print(f"  launchctl load {plist_path}")

Technical Analysis

Startup persistence is a declared part of the watchdog's intended 24/7 monitoring functionality and is installed only after user selection. It is therefore functionally justified and not a ...[truncated 2285 chars]

Remediation
View remediation

Remediation Suggestions

  1. Implement complete platform-specific uninstall functions.
  2. For Linux, uninstall should:
    • Run systemctl stop gateway-watchdog.
    • Run systemctl disable gateway-watchdog.
    • Remove the exact service file created during installation.
    • Run systemctl daemon-reload.
    • Verify that the service is inactive, disabled, and absent.
  3. For macOS, uninstall should:
    • Unload or boot out the exact LaunchAgent.
    • Remove ~/Library/LaunchAgents/com.openclaw.gateway-watchdog.plist.
    • Verify that no associated watchdog process remains.
  4. Track installation metadata so removal only affects artifacts created by this project.
  5. Make uninstall idempotent and report partial failures clearly.
  6. Do not default the Linux service account to root. Require an explicit, validated, non-root account.
  7. Apply service hardening such as NoNewPrivileges=true, a restrictive UMask, and appropriate filesystem protections.
  8. Document manual removal commands alongside every persistence installation method.
  9. Verify successful cleanup before displaying an uninstall success message.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (56)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The architecture doc explicitly shows that on failure the watchdog will kill node processes and restart the gateway automatically. While the behavior is documented as workflow steps, there is no clear warning to users that the skill can terminate running processes and disrupt service, which is the kind of system-integrity-impacting behavior that should be disclosed in markdown descriptions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The document advertises DingTalk robot notifications and instructs users to configure a webhook and secret, which implies the skill sends monitoring information over the network to a third-party service. However, the README does not clearly warn users that service status and related operational data will be transmitted externally.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
65% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 53)May include surrounding context.

md
python gateway_monitor.py

# 方式2: 后台运行(Linux/macOS)
nohup python gateway_monitor.py &

# 方式3: 使用安装脚本(推荐)
python install.py

Session Persistence

Medium
Category
Rogue Agent
Confidence
65% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · install.py (reported line 203)May include surrounding context.

python
python gateway_monitor.py

# 方式2: 后台运行(Linux/macOS)
nohup python gateway_monitor.py &

# 方式3: 使用安装脚本(推荐)
python install.py

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file states that the tool will use --force to restart the Gateway and explicitly mentions killing the old process, which can affect running work or service availability. The surrounding documentation describes the behavior but does not provide a user warning about the operational risk or possible interruption caused by this destructive action.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 126)May include surrounding context.

powershell
# 创建任务计划
schtasks /create /tn "OpenClaw Gateway Watchdog" /tr "python C:\path\to\gateway_monitor.py" /sc minute /mo 1 /rl limited /f

Linux (systemd)

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 150)May include surrounding context.

text

```bash
sudo systemctl enable gateway-watchdog
sudo systemctl start gateway-watchdog

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 151)May include surrounding context.

text

```bash
sudo systemctl enable gateway-watchdog
sudo systemctl start gateway-watchdog

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 150)May include surrounding context.

text

```bash
sudo systemctl enable gateway-watchdog
sudo systemctl start gateway-watchdog

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 158)May include surrounding context.

bash
# 编辑 crontab
crontab -e

# 添加(每分钟检查一次)
* * * * * cd /path/to/gateway-watchdog && python gateway_monitor.py >> /tmp/gateway-watchdog.log 2>&1

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 169)May include surrounding context.

xml
<!-- ~/Library/LaunchAgents/com.openclaw.gateway-watchdog.plist -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 188)May include surrounding context.

text

```bash
launchctl load ~/Library/LaunchAgents/com.openclaw.gateway-watchdog.plist

项目结构

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill explicitly promotes automatic installation, autostart setup, and automatic service execution without presenting a clear warning, consent checkpoint, or explanation of system changes. This is dangerous because it encourages users to run code from an external repository with persistence enabled, increasing the risk of unintended system modification or abuse if the repository is compromised or behaves unexpectedly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill describes automatic DingTalk notification configuration but does not warn users that operational events and potentially sensitive system status information may be transmitted to a remote webhook. This creates a privacy and data-handling risk because users may expose internal monitoring details or secrets to third-party messaging infrastructure without understanding what data leaves the host.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script performs forceful process termination automatically and silently, with broad targeting logic on both Windows and Unix-like systems. In this watchdog context that is dangerous because it can repeatedly kill unrelated processes without operator confirmation, amplifying denial-of-service impact.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
96% confidence
Finding

This forcibly kills every node.exe process on Windows rather than identifying the specific gateway instance. In a watchdog context, that can terminate unrelated applications and services, causing denial of service or data loss if the script runs with sufficient privileges.

Content

Scanner excerpt · gateway_monitor.py (reported line 146)May include surrounding context.

python
if system == "Windows":
        try:
            subprocess.run(["taskkill", "/F", "/IM", "node.exe"], 
                          capture_output=True, timeout=10)
        except Exception:
            pass

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
91% confidence
Finding

Using pkill -f openclaw kills processes by a broad pattern match, which can terminate unintended processes whose command lines contain openclaw. This is an unsafe process-management practice that can be abused or can accidentally disrupt other workloads on the host.

Content

Scanner excerpt · gateway_monitor.py (reported line 153)May include surrounding context.

python
else:  # Linux/Mac
        try:
            # 杀掉所有 node 进程(谨慎使用)
            subprocess.run(["pkill", "-f", "openclaw"], 
                          capture_output=True, timeout=10)
        except Exception:
            pass

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script silently restarts the gateway in a loop, which can mask failures, create restart storms, and repeatedly execute a binary resolved from PATH. In a security-sensitive environment, that increases operational risk and could execute an unintended binary if the environment is compromised.

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 · gateway_monitor.py (reported line 165)May include surrounding context.

python
try:
        if system == "Windows":
            # 使用 --force 强制重启
            subprocess.Popen(
                ["openclaw", "gateway", "--force"],
                stdout=subprocess.DEVNULL,
                stderr=subprocess.DEVNULL,

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 · gateway_monitor.py (reported line 172)May include surrounding context.

python
creationflags=subprocess.CREATE_NO_WINDOW if sys.platform == "win32" else 0
            )
        else:
            subprocess.Popen(
                ["openclaw", "gateway", "--force"],
                stdout=subprocess.DEVNULL,
                stderr=subprocess.DEVNULL,

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file’s user-facing description and prompts are presented only in Chinese, including installation guidance and menu text. This imposes a specific language on users without opt-in, which matches the language/locale policy violation criteria for natural-language content.

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 · install.py (reported line 21)May include surrounding context.

python
task_name = "OpenClawGatewayWatchdog"
    
    # 检查是否已存在
    result = subprocess.run(
        ["schtasks", "/query", "/tn", task_name],
        capture_output=True,
        text=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 · install.py (reported line 42)May include surrounding context.

python
"/f"
    ]
    
    result = subprocess.run(cmd, capture_output=True, text=True)
    
    if result.returncode == 0:
        print("✅ Windows 开机自启安装成功!")

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 · install.py (reported line 57)May include surrounding context.

python
"""Windows 卸载"""
    task_name = "OpenClawGatewayWatchdog"
    
    result = subprocess.run(
        ["schtasks", "/delete", "/tn", task_name, "/f"],
        capture_output=True,
        text=True

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
84% confidence
Finding

The script instructs the user to enable a systemd service with sudo, establishing privileged persistence for a local script. If the referenced script directory or files are writable by a less-privileged user, this can become a privilege boundary issue where root later executes attacker-modified code automatically.

Content

Scanner excerpt · install.py (reported line 103)May include surrounding context.

python
print(service_content)
        print("-" * 40)
        print("然后运行:")
        print(f"  sudo systemctl enable {service_name}")
        print(f"  sudo systemctl start {service_name}")
        return True
    except Exception as e:

Static analysis

No suspicious patterns detected.