Back to skill

Security audit

Gateway Monitor Installer

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a disclosed macOS monitor installer, but it includes under-disclosed network-exposed monitoring, credential use, and a configuration-restore endpoint that can change local OpenClaw state.

Review before installing. This skill should be treated as requiring trust in a persistent local service, not just a simple installer. It can read OpenClaw logs/session data, use a MiniMax credential from the local auth profile, make outbound requests, expose unauthenticated HTTP APIs on the network, and change the active OpenClaw config through a GET endpoint. Prefer a version that binds only to localhost, requires authentication for APIs, removes or gates config restore, documents credential use, and includes the missing LaunchAgent templates.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
assets/bin/gateway-monitor-server.js:28
Finding

Authentication Credential Transmitted to a Configurable Remote Endpoint

Content
View full analysis
{ const u = new URL(urlString); const req = https.request({ protocol: u.protocol, hostname: u.hostname, port: u.port || 443, path: `${u.pathname}${u.search}`, method: 'GET', headers, timeout: timeoutMs }, (res) => { let body = ''; res.setEncoding('utf8'); res.on('data', (chunk) => { body += chunk; }); res.on('end', () => { if (res.statusCode < 200 || res.statusCode >= 300) { return reject(new Error(`HTTP ${res.statusCode}: ${body.slice(0, 220)}`)); } try { resolve(JSON.parse(body)); } catch (err) { reject(new Error(`JSON parse failed: ${e ...[truncated 2482 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
assets/bin/gateway-monitor-server.js:1111
Finding

Sensitive Monitoring APIs Exposed on All Network Interfaces Without Authentication

Content
View full analysis
{ const parsed = url.parse(req.url, true); const pathname = parsed.pathname; if (pathname === '/') return serveIndex(res); if (pathname === '/api/logs/stream') { return handleLogStream(req, res, parsed.query || {}); } if (pathname === '/api/minimax-coding-plan') { const force = String(parsed.query.force || '').trim() === '1'; loadMiniMaxCodingPlan(force) .then((payload) => json(res, payload)) .catch((err) => json(res, { now: new Date().toISOString(), ok: false, statusMsg: 'request_failed', keyMasked: null, source: null, windowHours: 5, models: [], error: String(err?.message || err) }, 500)); return; } if (pathname === '/api/gateway-status') { const gateway = gatewayStatus(); return json(res, { now: new Date().toISOString(), gateway, model: currentModel(), context: sessionContextStatus(), metrics: buildMetrics(gateway) }); } if (pathname === '/api/context-status') { return json(res, { now: new Date().toISOString(), context: sessionContextStatus() }); } if (pathname === '/api/sessions') { const ctx = sessionContextStatus(); return json(res, { now: new Date().toISOString(), ok: ctx.ok, primary: ctx.ok ? { percentUsed: ctx.percentUsed, totalTokens: ctx.totalTokens, contextTokens: ctx.contextTokens, remainingTokens: ctx.remainingTokens, model: ctx.model, abortedLastRun: ctx.abortedLastRun } : null, sessions: ctx.sessions || [], error: ctx.error || null }); } if (pathname === '/api ...[truncated 2930 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
assets/bin/gateway-monitor-server.js:1208
Finding

Unauthenticated GET Endpoint Can Overwrite the Active OpenClaw Configuration

Content
View full analysis
f.startsWith('openclaw.json.bak.')) .map(f => { const p = path.join(configBackupDir, f); return { name: f, path: p, mtime: fs.statSync(p).mtimeMs }; }) .sort((a, b) => b.mtime - a.mtime); if (backupFiles.length === 0) { return json(res, { ok: false, error: 'No backup files found', configBackupDir }, 404); } const latestBackup = backupFiles[0].name; const backupPath = backupFiles[0].path; // 复制备份到配置文件 fs.copyFileSync(backupPath, openclawJsonPath); // 验证 JSON 格式 const content = fs.readFileSync(openclawJsonPath, 'utf8'); JSON.parse(content); // 如果无效会抛出异常 return json(res, { ok: true, restored: latestBackup, backupPath, configPath: openclawJsonPath, message: 'Configuration restored successfully. Gateway restart may be required.' }); } catch (err) { return json(res, { ok: false, ...[truncated 2011 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
assets/bin/gateway-monitor-server.js:24
Finding

Environment-Controlled Shell Commands Permit Arbitrary Command Execution

Content
View full analysis
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (41)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared purpose is a local installer/manager, but the detected behavior includes operating a local monitoring API server, exposing diagnostics/log streaming endpoints, reading auth material, restoring configs, and reaching out to an external service. This mismatch is dangerous because users and orchestrators may grant trust for a simple installer while the skill actually handles sensitive data and network-facing functionality beyond that scope.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- If node path differs, edit `assets/bin/gateway-watchdog.sh` before install

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The monitoring server exposes functionality outside the declared install/update/run/remove/health-check scope by adding a configuration restore capability that overwrites ~/.openclaw/openclaw.json. Because this is served over the same HTTP interface and not gated by authentication or stronger authorization, it expands the attack surface from passive monitoring into active state-changing administration.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The /api/restore-config route performs a state-changing file overwrite via unauthenticated HTTP GET with only a query-string confirm=true check. Since the server listens on 0.0.0.0, any reachable host or browser-triggered request from the local network could invoke the restore, enabling unauthorized rollback of configuration and possible service disruption.

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/status.sh (reported line 21)May include surrounding context.

sh
print_agent "$MONITOR_LABEL"
print_agent "$WATCHDOG_LABEL"

rm -f /tmp/.gm_status.$$

echo "\n[health]"
if command -v curl >/dev/null 2>&1; then

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/uninstall.sh (reported line 23)May include surrounding context.

sh
unload_agent "$WATCHDOG_LABEL"

echo "[uninstall] removing plist files"
rm -f "$LAUNCH_DIR/${MONITOR_LABEL}.plist"
rm -f "$LAUNCH_DIR/${WATCHDOG_LABEL}.plist"

echo "[uninstall] removing binaries"

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/uninstall.sh (reported line 24)May include surrounding context.

sh
echo "[uninstall] removing plist files"
rm -f "$LAUNCH_DIR/${MONITOR_LABEL}.plist"
rm -f "$LAUNCH_DIR/${WATCHDOG_LABEL}.plist"

echo "[uninstall] removing binaries"
rm -rf "$TARGET_BASE"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill invokes shell-based installer, status, and uninstall scripts but declares no explicit tool scope or permission boundaries. That makes its effective capabilities broader and less transparent to the user or calling agent, increasing the chance of unintended command execution and unsafe system changes.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The skill is explicitly designed to create or manage LaunchAgent-based services, which establishes persistence across user sessions. Even if intended for legitimate monitoring, persistence increases risk because compromised or misconfigured components will automatically restart and continue running in the background.

Content

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

md
---
name: gateway-monitor-installer
description: Install, update, run, and remove OpenClaw Gateway Monitor + Gateway Watchdog on macOS via LaunchAgent. Use when user asks to deploy one-click monitoring, recover broken gateway daemon automatically, check launchctl health, or uninstall monitor/watchdog services.
---

# Gateway Monitor Installer

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill describes installing binaries, writing LaunchAgents, backing up configuration, enabling services, and uninstalling them, but does not prominently warn that it will persist processes and modify user files. Without an explicit warning, users may trigger system-impacting changes without understanding persistence, rollback implications, or service side effects.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The LaunchAgent/plist workflow shows the skill writes service definitions into the user's LaunchAgents directory and bootstraps them, creating durable session persistence. This is security-relevant because persistent agents can keep running local servers, watchdog logic, or recovery routines beyond the user's immediate session intent.

Content

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

md
- Copy monitor and watchdog binaries to `~/.openclaw/tools/gateway-monitor/bin/`
- Render LaunchAgent templates into `~/Library/LaunchAgents/`
- Backup existing plist files to `~/.openclaw/config-backups/`
- Bootstrap + enable + kickstart both agents
- Run post-install status check

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The service includes unrelated MiniMax API integration and credential lookup from environment variables and a local auth profile, which is not necessary for basic gateway monitoring. This broadens the privilege and data-access scope of the process, increasing the blast radius if the monitor is compromised and creating undisclosed outbound data flow.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code loads a MiniMax API key from environment or a local auth profile and makes outbound authenticated requests without clear user-facing disclosure in a service marketed as a gateway monitor. Even if the key is masked in responses, the silent credential access and network egress violate least surprise and can expose billing, metadata, and trust boundaries.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The restore operation overwrites a live configuration file after only a trivial query parameter confirmation and without substantial warning, preview, or rollback safeguards. This makes accidental or induced restores easier and can cause loss of intended configuration, service instability, or reintroduction of insecure settings from old backups.

Content

No source excerpt is available for this finding.

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 · assets/bin/gateway-watchdog.sh (reported line 16)May include surrounding context.

sh
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0

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 · assets/bin/gateway-watchdog.sh (reported line 17)May include surrounding context.

sh
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0

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 · assets/bin/gateway-watchdog.sh (reported line 18)May include surrounding context.

sh
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0

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 · assets/bin/gateway-watchdog.sh (reported line 30)May include surrounding context.

sh
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0

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 · assets/bin/gateway-watchdog.sh (reported line 31)May include surrounding context.

sh
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0

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 · assets/bin/gateway-watchdog.sh (reported line 32)May include surrounding context.

sh
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0

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

sh
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0

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 · scripts/install.sh (reported line 22)May include surrounding context.

sh
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0

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 · scripts/install.sh (reported line 24)May include surrounding context.

sh
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0

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 · scripts/install.sh (reported line 25)May include surrounding context.

sh
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0

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 · scripts/install.sh (reported line 55)May include surrounding context.

sh
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0