Back to skill

Security audit

Gateway Watchdog

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real Gateway watchdog, but it can start a persistent local process and has unsafe unverified code/dependency execution paths.

Review this carefully before installing. Do not run it as administrator/root, avoid the one-click installer unless the bundled gateway_watchdog.py is present and reviewed, and make sure OpenClaw is installed from a trusted source so the npx fallback is not used. Install only if you explicitly want a background process that can keep restarting Gateway under your account.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
install.py:13
Finding

Unverified Remote Python Payload Download and Execution

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
gateway_watchdog.py:90
Finding

Implicit Execution of an Unpinned Package Through npx

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (30)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
96% confidence
Finding

This tool invocation combines npx with shell=True, which increases the chance of unsafe parameter interpretation and supply-chain abuse. In an agent skill context, any external tool execution that can dynamically resolve packages is especially dangerous because it extends trust beyond the local codebase.

Content

Scanner excerpt · gateway_watchdog.py (reported line 90)May include surrounding context.

python
# 尝试 npx
        try:
            result = subprocess.run(
                ["npx", "openclaw", "--version"],
                capture_output=True,
                timeout=10,

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

The PID filter for tasklist is constructed from file-sourced data and executed via the shell, enabling parameter and command injection. Because PID files are often writable or replaceable in weakly secured deployments, this is a practical abuse path.

Content

Scanner excerpt · gateway_watchdog.py (reported line 212)May include surrounding context.

python
try:
            # 检查进程是否存在
            if platform.system() == "Windows":
                result = subprocess.run(
                    f"tasklist /FI \"PID eq {old_pid}\"",
                    capture_output=True,
                    text=True,

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

The taskkill command uses shell interpolation of a PID file value, making arbitrary shell command injection possible. This can let an attacker escalate from file tampering to code execution in the watchdog's security context.

Content

Scanner excerpt · gateway_watchdog.py (reported line 284)May include surrounding context.

python
try:
        if platform.system() == "Windows":
            subprocess.run(f"taskkill /PID {pid} /F", shell=True)
        else:
            os.kill(int(pid), signal.SIGTERM)
        PID_FILE.unlink()

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

This status-check path repeats the same shell-based tasklist pattern using PID file data. An attacker who controls the PID file can trigger command execution when an operator checks service status.

Content

Scanner excerpt · gateway_watchdog.py (reported line 304)May include surrounding context.

python
pid = f.read().strip()
        try:
            if platform.system() == "Windows":
                result = subprocess.run(
                    f"tasklist /FI \"PID eq {pid}\"",
                    capture_output=True,
                    text=True,

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This installer fetches a Python script from a remote GitHub URL and immediately executes it later without any checksum, signature, pinning, or trust verification. That creates a remote code execution supply-chain risk: if the repository, branch content, network path, or hosting account is compromised, users will run attacker-controlled code under their own privileges.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Most of the README's operational instructions and descriptions are written in Chinese, and there is no indication that users may choose another language or that the locale restriction is intentional for a region-specific audience. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger phrases are broad, generic operational requests such as 'keep Gateway running' and 'set watchdog', which could be matched in ordinary conversation without clearly signaling consent to download software or start a persistent process. In this skill’s context, accidental invocation is more dangerous because the described behavior includes fetching code from GitHub and launching a long-running watchdog process.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill instructs the agent to download gateway_watchdog.py from GitHub if missing and execute it, but it does not warn the user about network access, remote code retrieval, or the creation of a persistent watchdog process. This is dangerous because it enables silent system modification and execution of unverified external code, increasing the risk of supply-chain compromise or unauthorized persistence.

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_watchdog.py (reported line 55)May include surrounding context.

python
# 首先尝试直接调用 (可能已经在 PATH 中)
    try:
        result = subprocess.run(
            ["openclaw", "--version"],
            capture_output=True,
            timeout=10,

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_watchdog.py (reported line 77)May include surrounding context.

python
for p in paths_to_try:
            try:
                result = subprocess.run(
                    [str(p), "--version"],
                    capture_output=True,
                    timeout=10,

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The code references npx as part of runtime tool discovery without pinning a package version. npx can resolve packages dynamically, which creates supply-chain risk and non-deterministic execution behavior if the package source or local environment is compromised.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

Running npx openclaw --version with shell=True introduces unnecessary shell exposure and also trusts npx to resolve and potentially fetch a package dynamically. In a compromised environment, PATH hijacking or malicious package resolution can result in execution of attacker-controlled code.

Content

Scanner excerpt · gateway_watchdog.py (reported line 90)May include surrounding context.

python
# 尝试 npx
        try:
            result = subprocess.run(
                ["npx", "openclaw", "--version"],
                capture_output=True,
                timeout=10,

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding

Persisting npx openclaw as the command means later watchdog operations may invoke an unpinned package executor repeatedly. This expands supply-chain exposure from one-time discovery to routine operational execution.

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_watchdog.py (reported line 112)May include surrounding context.

python
for p in paths_to_try:
            try:
                result = subprocess.run(
                    [str(p), "--version"],
                    capture_output=True,
                    timeout=10

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
91% confidence
Finding

cmd is derived from the persisted configuration value openclaw_cmd, and this command is executed with shell=True on Windows. If an attacker can modify gateway_watchdog.json or influence command discovery earlier, they can cause arbitrary command execution whenever the watchdog performs a status check.

Content

Scanner excerpt · gateway_watchdog.py (reported line 145)May include surrounding context.

python
"""检查 Gateway 是否正常运行"""
    try:
        cmd = get_openclaw_cmd() + ["gateway", "status"]
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
91% confidence
Finding

This restart path executes openclaw_cmd from configuration with shell=True on Windows. Because the watchdog automatically triggers this code after repeated failures, a maliciously altered config can yield repeated arbitrary command execution with the privileges of the watchdog process.

Content

Scanner excerpt · gateway_watchdog.py (reported line 162)May include surrounding context.

python
try:
        log("Gateway 连续失败,准备重启...")
        cmd = get_openclaw_cmd() + ["gateway", "restart"]
        subprocess.run(
            cmd,
            capture_output=True,
            text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
98% confidence
Finding

old_pid is read from a PID file and inserted into a shell command string for tasklist. A maliciously modified PID file could inject additional shell commands on Windows, making this a straightforward command-injection issue.

Content

Scanner excerpt · gateway_watchdog.py (reported line 212)May include surrounding context.

python
try:
            # 检查进程是否存在
            if platform.system() == "Windows":
                result = subprocess.run(
                    f"tasklist /FI \"PID eq {old_pid}\"",
                    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 · gateway_watchdog.py (reported line 247)May include surrounding context.

python
if platform.system() == "Windows":
        # Windows: 用 start /b 后台运行
        proc = subprocess.Popen(
            [sys.executable, __file__, "run"],
            stdout=open(LOG_FILE, "a"),
            stderr=subprocess.STDOUT,

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

python
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
        )
    else:
        # Linux: nohup
        proc = subprocess.Popen(
            ["nohup", sys.executable, __file__, "run"],
            stdout=open(LOG_FILE, "a"),

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_watchdog.py (reported line 256)May include surrounding context.

python
)
    else:
        # Linux: nohup
        proc = subprocess.Popen(
            ["nohup", sys.executable, __file__, "run"],
            stdout=open(LOG_FILE, "a"),
            stderr=subprocess.STDOUT,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
98% confidence
Finding

The pid value is read from a writable PID file and interpolated directly into a shell command: taskkill /PID {pid} /F. If an attacker can alter the PID file, they can inject additional shell syntax and execute arbitrary commands on Windows.

Content

Scanner excerpt · gateway_watchdog.py (reported line 284)May include surrounding context.

python
try:
        if platform.system() == "Windows":
            subprocess.run(f"taskkill /PID {pid} /F", shell=True)
        else:
            os.kill(int(pid), signal.SIGTERM)
        PID_FILE.unlink()

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_watchdog.py (reported line 304)May include surrounding context.

python
pid = f.read().strip()
        try:
            if platform.system() == "Windows":
                result = subprocess.run(
                    f"tasklist /FI \"PID eq {pid}\"",
                    capture_output=True,
                    text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
90% confidence
Finding

This status command again executes openclaw_cmd from configuration with shell=True on Windows. Any compromise of the config file or path discovery mechanism can be turned into arbitrary command execution when a user checks watchdog status.

Content

Scanner excerpt · gateway_watchdog.py (reported line 330)May include surrounding context.

python
print("=" * 50)
    try:
        cmd = get_openclaw_cmd() + ["gateway", "status"]
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
90% confidence
Finding

Manual restart uses the same untrusted openclaw_cmd value with shell=True on Windows. This allows malicious config tampering to execute arbitrary OS commands when an operator invokes the restart function.

Content

Scanner excerpt · gateway_watchdog.py (reported line 356)May include surrounding context.

python
log("手动重启 Gateway...")
    try:
        cmd = get_openclaw_cmd() + ["gateway", "restart"]
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file’s user-facing description is entirely in Chinese and presents the skill as a one-click installer without any indication that another language is available. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is documented and justified.

Content

No source excerpt is available for this finding.