Back to skill

Security audit

Auto-Heal

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real OpenClaw auto-heal monitor, but it can repeatedly restart services, kill sessions, and delete logs while ignoring documented safety controls.

Review this before installing in any active OpenClaw environment. Use it only under an account whose OpenClaw sessions and logs you are willing to let it mutate, and do not rely on enabled=false or autoFix=false unless the code is fixed to enforce those settings. Avoid cron/nohup deployment until command execution is made shell-safe and destructive repairs are gated or dry-run capable.

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

T09 · Insecure Skill Coding Practices

Error
Location
monitor.js:150
Finding

Shell Command Injection Through Unvalidated Session IDs

Content
View full analysis

Vulnerability Details

File Location: monitor.js, lines 150-153
Vulnerability Type: OS command injection
Risk Level: High

Vulnerable Code

js
for (const session of sessions) {
  log('INFO', `Killing zombie session: ${session.id}`);
  
  const result = runCommand(`openclaw sessions kill ${session.id}`, 5000);

The session.id value originates from JSON returned by:

js
const result = runCommand('openclaw sessions list --json', 10000);
const sessions = JSON.parse(result.output);

Technical Analysis

The Skill builds a shell command by directly interpolating session.id into a string passed to runCommand(). That function invokes the command through child_process.execSync(), which executes it using a shell:

js
function runCommand(cmd, timeout = 10000) {
  try {
    const result = execSync(cmd, { 
      encoding: 'utf8', 
      timeout,
      stdio: ['pipe', 'pipe', 'pipe']
    });

No identifier validation, argument escaping, or shell-free process invocation is applied. Consequently, shell metacharacters embedded in a session identifier can terminate or alter the intended command and introduce additional commands.

Although the session list is obtained from the local OpenClaw CLI, it must not be treated as inherently safe. Exploitation is possible if an attacker can influence stored session metadata, the CLI output, or another component responsible for creating session identifiers.

Attack Path

  1. An attacker causes openclaw sessions list --json to return a session whose id contains shell metacharacters and an injected command.
  2. The attacker ensures that the session has a busy status and a lastActivity value older than the configured 30-minute threshold.
  3. checkAgentSessions() classifies the crafted session as a zombie session.
  4. healthCheck() passes the session to fixZombieSessions().
  5. The crafted identifier is interpolat ...[truncated 954 chars]
Remediation
View remediation

Remediation Suggestions

Replace shell-based command execution with a shell-free API and pass each argument separately:

js
const { execFileSync } = require('child_process');

function runOpenClaw(args, timeout = 10000) {
  try {
    const output = execFileSync('openclaw', args, {
      encoding: 'utf8',
      timeout,
      stdio: ['ignore', 'pipe', 'pipe'],
      shell: false
    });

    return { success: true, output: output.trim() };
  } catch (error) {
    return {
      success: false,
      error: error.message,
      output: error.stdout?.trim() || ''
    };
  }
}

const sessionId = String(session.id);
const result = runOpenClaw(['sessions', 'kill', sessionId], 5000);

In addition:

  1. Validate session IDs against the exact identifier format documented by OpenClaw, such as a strict UUID validator where applicable.
  2. Reject identifiers containing whitespace, control characters, shell metacharacters, or unexpected Unicode characters.
  3. Apply length limits before logging or using identifiers.
  4. Use separate argument arrays for every OpenClaw invocation rather than accepting general shell command strings.
  5. Run the monitor as a dedicated, unprivileged account with access limited to the necessary OpenClaw resources.
  6. Add tests containing hostile identifiers to verify that they are rejected or passed only as literal arguments.

T09 · Insecure Skill Coding Practices

Warning
Location
monitor.js:211
Finding

Documented Safety Controls Are Ignored During Destructive Automatic Repair

Content
View full analysis

Vulnerability Details

File Location: monitor.js, lines 211-235
Vulnerability Type: Unsafe configuration handling and unconditional destructive actions
Risk Level: Medium

Vulnerable Code

js
// 1. 检查 Gateway
const gatewayStatus = await checkGateway();
if (!gatewayStatus.healthy) {
  issues.push({ component: 'gateway', ...gatewayStatus });
  
  // 自动修复
  const fix = await fixGateway();
  if (!fix.fixed) {
    log('ERROR', 'Failed to auto-fix gateway');
  }
}

// 2. 检查 Agent 会话
const sessionStatus = await checkAgentSessions();
if (!sessionStatus.healthy) {
  issues.push({ component: 'sessions', ...sessionStatus });
  
  // 自动修复僵尸会话
  if (sessionStatus.sessions) {
    await fixZombieSessions(sessionStatus.sessions);
  }
}

// 3. 检查资源
const resourceStatus = await checkResources();
if (!resourceStatus.healthy) {
  issues.push({ component: 'resources', ...resourceStatus });
  
  // 自动修复资源问题
  await fixResources();
}

The installer writes controls such as enabled and autoFix to ~/.openclaw/openclaw.json:

js
config.skills['auto-heal'] = {
  enabled: true,
  checkInterval: 60,
  autoFix: true,
  memoryThreshold: 80,
  zombieSessionAge: 30,
  notifyChannel: '',
  logRetentionDays: 7
};

However, monitor.js uses only its hardcoded configuration:

js
const CONFIG = {
  checkInterval: 60 * 1000,
  gatewayTimeout: 30 * 1000,
  memoryThreshold: 80,
  zombieSessionAge: 30 * 60 * 1000,
  logFile: path.join(__dirname, 'logs', 'auto-heal.log'),
  stateFile: path.join(__dirname, 'state.json')
};

Technical Analysis

The documentation and installer represent enabled, autoFix, monitoring thresholds, and retention settings as effective user controls. The runtime does not load the OpenClaw configuration file and does not test either enabled or autoFix before performing state-changing operations.

As ...[truncated 2116 chars]

Remediation
View remediation

Remediation Suggestions

  1. Load ~/.openclaw/openclaw.json at startup and validate the skills.auto-heal object against a strict schema.
  2. Exit without performing checks or mutations when enabled !== true.
  3. Gate every state-changing operation behind an explicit autoFix === true check:
    • Gateway restart
    • Session termination
    • Log deletion
    • Resource-remediation restart
  4. Default to monitoring-only behavior when configuration is missing, malformed, or ambiguous.
  5. Use the configured values for checkInterval, memoryThreshold, zombieSessionAge, and logRetentionDays rather than hardcoded alternatives.
  6. Distinguish an unhealthy gateway from an inconclusive check. Do not restart services merely because CLI execution failed or output formatting changed.
  7. Require multiple consecutive failed checks or an explicit confirmation signal before destructive repair.
  8. Record whether each issue was detected, repaired, skipped by policy, or unsuccessfully repaired. Do not report all detected issues as automatically fixed.
  9. Provide a dry-run mode and document how users can reliably disable both monitoring and mutation.
  10. Add tests proving that enabled: false and autoFix: false prevent all corresponding operations.
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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (15)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README prominently advertises automatic restarts, session cleanup, and memory protection, but it does not clearly warn users that these actions may terminate active processes or delete state in ways that disrupt service. In an operations automation skill, undocumented self-healing behavior can cause unintended downtime, loss of in-memory work, or interference with legitimate long-running sessions.

Content

No source excerpt is available for this finding.

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 40)May include surrounding context.

bash
# 编辑 crontab
crontab -e

# 添加每 5 分钟检查一次
*/5 * * * * cd ~/.openclaw/workspace/skills/auto-heal && npm run check

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

js
```bash
# 编辑 crontab
crontab -e

# 添加每 5 分钟检查一次
*/5 * * * * cd ~/.openclaw/workspace/skills/auto-heal && npm run check

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.

npm start

或后台运行

nohup npm start > /dev/null 2>&1 &

text

#### 方法3:手动检查

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 · README.md (reported line 129)May include surrounding context.

md
### 检查不生效?

1. 确认 OpenClaw CLI 可用:`which openclaw`
2. 检查配置文件权限:`ls -la ~/.openclaw/openclaw.json`
3. 查看日志错误:`tail -n 50 logs/auto-heal.log`

### 自动修复失败?

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases are broad operational terms like '自动重启', '健康检查', and '守护进程' that can easily match ordinary support or diagnostic requests. Because this skill performs automatic restart and cleanup actions, accidental activation could cause unintended service disruption or deletion of active/zombie-classified sessions without explicit user consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill describes automatic restart, cleanup, and zombie-session removal behavior but does not prominently warn that these actions may interrupt running work or remove local session state. In context, the lack of disclosure increases the chance that users or operators enable it without understanding the operational and data-loss consequences.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
78% confidence
Finding

The nohup background execution command creates an unattended long-running process detached from the terminal, which is a form of process persistence. While common for legitimate daemons, in this context it reduces visibility and may allow automatic remediation actions to continue without active supervision, increasing operational risk if the script malfunctions.

Content

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

node ~/.openclaw/workspace/skills/auto-heal/monitor.js

后台运行

nohup node ~/.openclaw/workspace/skills/auto-heal/monitor.js > /dev/null 2>&1 &

text

### 使用 Cron 定时任务(推荐)

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% confidence
Finding

Recommending installation via crontab establishes recurring execution, which is a persistence mechanism. In this skill's context the persistence appears intended for legitimate monitoring, but it still creates long-lived autonomous behavior that can repeatedly restart services or clean sessions, magnifying the effect of bugs, misconfiguration, or unauthorized deployment.

Content

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

使用 Cron 定时任务(推荐)

bash
# 编辑 crontab
crontab -e

# 添加每5分钟检查一次
*/5 * * * * cd ~/.openclaw/workspace/skills/auto-heal && node monitor.js --check-once

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script automatically kills sessions it classifies as zombie based on age and status, with no operator approval or safety checks beyond simple heuristics. Misclassification can terminate legitimate long-running work, causing denial of service, loss of progress, or disruption of active agent tasks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The monitor automatically deletes log files via a shell command without any user confirmation, dry-run mode, retention safeguards beyond age matching, or visibility outside internal logs. In an operational skill that runs continuously, this can destroy forensic evidence or unexpectedly remove data an operator intended to keep, especially after compromise or failure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The package description is entirely in Chinese, which imposes a specific language presentation without offering any user opt-in or alternative locale. The policy for this audit flags language/locale constraints in natural-language content when no choice or justification is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill documentation is entirely in Chinese and does not indicate that language selection is optional or that the skill is intended only for a Chinese-speaking audience. This can violate language/locale policy when a skill implicitly requires a specific language without user opt-in or documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The file header mixes an English title with a Chinese-only descriptive phrase, "一键安装和配置," without indicating that the skill is intended for a Chinese-speaking audience or offering an opt-in language choice. Under the language/locale policy, forcing or assuming a specific language without user choice can be a natural-language policy issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The natural-language description is written as a Chinese-only statement in the header comment, with no indication that language is selectable or that the tool is intentionally region-specific. This may violate language/locale policy when a skill implicitly constrains communication to one language without user opt-in.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
install.js:19

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
monitor.js:42