Back to skill

Security audit

API配额监控与手动切换

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly purpose-aligned, but its model-switching path can rewrite OpenClaw configuration and restart processes without a built-in confirmation check or tightly scoped process targeting.

Install only if you are comfortable with a skill that can change your OpenClaw model configuration and restart the Gateway. Run it as a normal user, not root, review any --confirm or --model invocation before allowing it, and be cautious with the cron example and custom log/config paths.

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

T09 · Insecure Skill Coding Practices

Warning
Location
api_monitor.py:82
Finding

Overbroad Process Matching Can Terminate Unrelated Processes

Content
View full analysis

Vulnerability Details

File Location: api_monitor.py, lines 82–89
Vulnerability Type: Overbroad process termination
Risk Level: Medium

Complete Code Snippet

python
# Restart Gateway (requires corresponding permissions)
subprocess.run(["pkill", "-f", "openclaw-gateway"], capture_output=True)
time.sleep(2)
subprocess.Popen(
    ["nohup", "openclaw", "gateway", "start"],
    stdout=open(OPENCLAW_LOG, "a"),
    stderr=subprocess.STDOUT
)

Technical Analysis

The model-switching function uses pkill -f openclaw-gateway to stop the existing Gateway. The -f option compares the supplied pattern against each process's entire command line rather than identifying one verified Gateway process.

Consequently, the command may terminate any process accessible to the invoking user if its command line contains openclaw-gateway, including unrelated applications or multiple Gateway instances. The implementation does not verify the matched process's executable, owner, PID, start time, or relationship to the OpenClaw installation.

The return code from pkill is also ignored. The code attempts to start another Gateway after a fixed two-second delay regardless of whether termination succeeded. This may leave duplicate instances or an inconsistent service state. The use of an argument-list subprocess call prevents shell command injection here, but it does not mitigate the unsafe breadth of the process match.

Attack Path

  1. An attacker or another local workload starts a process whose command line contains the text openclaw-gateway.
  2. A user or agent invokes the Skill with --confirm or --model, causing set_model() to run.
  3. The Skill executes pkill -f openclaw-gateway.
  4. The operating system terminates every accessible process whose full command line matches the pattern, including the unrelated process.
  5. The Skill waits two seconds and attempts to start a new Gateway without checking whether the intended process was stopped su ...[truncated 928 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace pkill -f with OpenClaw's supported restart command or a service-manager operation scoped to the exact Gateway service.
  2. If no supported service interface exists, record the Gateway PID in a protected PID file and validate all of the following before signaling it:
    • The PID is numeric and currently active.
    • The process is owned by the expected account.
    • The executable resolves to the expected OpenClaw binary.
    • The process start time matches the managed instance, preventing PID-reuse errors.
  3. Send a graceful termination signal to only the verified PID, wait with a bounded timeout, and escalate only when explicitly necessary.
  4. Check and handle the termination command's return status.
  5. Confirm that the prior Gateway has exited before starting a replacement.
  6. Check startup success and report failures rather than returning success immediately after Popen.
  7. Avoid running the Skill with elevated privileges; use a dedicated, least-privileged account with access only to the required OpenClaw configuration and service.
  8. Where concurrent invocations are possible, use a lock file to prevent overlapping restarts and duplicate Gateway instances.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (12)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The description and trigger phrases are entirely specified in Chinese, and the example interaction later in the file is also Chinese-only. This indicates a language-specific constraint without any explicit user opt-in or justification that the skill is region-specific, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

File System Enumeration

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Content

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

python3 --version

确认脚本存在(路径根据实际安装位置调整)

ls -la ~/.openclaw/skills/api-monitor/api_monitor.py

text

### 查看当前状态

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% confidence
Finding

The skill instructs users to configure a cron job for periodic execution, which establishes persistence on the host. Although presented as an optional operational convenience, persistence mechanisms are security-relevant because they cause repeated execution of a script that can modify configuration and potentially restart services, increasing the blast radius if the script is altered or misused.

Content

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

如需定时自动检查,可配置 cron:

bash
# 编辑 crontab
crontab -e

# 添加定时任务(每30分钟检查一次)
# 替换为实际路径

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The docstring states model switching requires user confirmation, but the implementation allows direct switching via --confirm and --model without any actual confirmation prompt. This mismatch can mislead users or reviewers into trusting a safety property that the code does not enforce, increasing the chance of unintended configuration changes and service restarts.

Content

No source excerpt is available for this finding.

Tainted flow: 'LOG_FILE' from os.environ.get (line 22, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
90% confidence
Finding

LOG_FILE comes from an environment-controlled directory and is opened in append mode without validation. In a privileged execution context, this can be abused to write attacker-controlled content to arbitrary filesystem locations or to follow symlinks into sensitive files.

Content

Scanner excerpt · api_monitor.py (reported line 42)May include surrounding context.

python
print(log_msg)
    try:
        os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True)
        with open(LOG_FILE, "a") as f:
            f.write(log_msg + "\n")
    except Exception:
        pass  # 日志写入失败不影响主流程

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code performs a file write to the user's OpenClaw configuration, which is a safety-relevant action affecting system behavior. Although the module docstring mentions path configuration and user confirmation before switching, it does not explicitly disclose that the tool will overwrite the config file on disk.

Content

No source excerpt is available for this finding.

Tainted flow: 'CONFIG_FILE' from os.environ.get (line 21, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
94% confidence
Finding

CONFIG_FILE is influenced by environment variables and CLI input, then opened for writing without trust-boundary checks. If the script is executed with elevated privileges, an attacker could point it at an arbitrary file and have JSON content written there, enabling destructive overwrite or configuration tampering.

Content

Scanner excerpt · api_monitor.py (reported line 75)May include surrounding context.

python
config["agents"]["defaults"]["model"]["primary"] = model
        
        with open(CONFIG_FILE, "w") as f:
            json.dump(config, f, indent=2, ensure_ascii=False)
        
        log(f"已切换模型到: {model}")

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

python
log(f"已切换模型到: {model}")
        
        # 重启Gateway(需要相应权限)
        subprocess.run(["pkill", "-f", "openclaw-gateway"], capture_output=True)
        time.sleep(2)
        subprocess.Popen(
            ["nohup", "openclaw", "gateway", "start"],

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

python
# 重启Gateway(需要相应权限)
        subprocess.run(["pkill", "-f", "openclaw-gateway"], capture_output=True)
        time.sleep(2)
        subprocess.Popen(
            ["nohup", "openclaw", "gateway", "start"],
            stdout=open(OPENCLAW_LOG, "a"),
            stderr=subprocess.STDOUT

Tainted flow: 'OPENCLAW_LOG' from os.environ.get (line 24, credential/environment) → subprocess.Popen (code execution)

Medium
Category
Data Flow
Confidence
88% confidence
Finding

OPENCLAW_LOG is derived from environment variables or CLI-controlled paths and is opened for append when spawning the child process. If this script runs with higher privileges, an attacker who controls LOG_DIR could redirect writes to arbitrary files via path manipulation or symlinks, causing file clobbering or unintended modification.

Content

Scanner excerpt · api_monitor.py (reported line 83)May include surrounding context.

python
# 重启Gateway(需要相应权限)
        subprocess.run(["pkill", "-f", "openclaw-gateway"], capture_output=True)
        time.sleep(2)
        subprocess.Popen(
            ["nohup", "openclaw", "gateway", "start"],
            stdout=open(OPENCLAW_LOG, "a"),
            stderr=subprocess.STDOUT

Tainted flow: 'OPENCLAW_LOG' from os.environ.get (line 24, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
88% confidence
Finding

This is the same underlying issue as the OPENCLAW_LOG flow to subprocess output redirection: an externally influenced path is opened for writing without validation. The danger is arbitrary file append/clobber in the context of the script's privileges, especially in shared or multi-user environments.

Content

Scanner excerpt · api_monitor.py (reported line 85)May include surrounding context.

python
time.sleep(2)
        subprocess.Popen(
            ["nohup", "openclaw", "gateway", "start"],
            stdout=open(OPENCLAW_LOG, "a"),
            stderr=subprocess.STDOUT
        )

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The function named and documented as asking the user for confirmation only prints a message and always returns True, so no user input is collected or verified. In a skill context, this is dangerous because it creates a false sense of human approval around an operation that edits configuration and restarts a service.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.