Back to skill

Security audit

Openclaw Push Doctor

Security checks for vulnerabilities and agentic risk

Overview

This healthcheck skill appears purpose-aligned, but its repair instructions can expose messaging credentials/configuration and make broad cron changes that deserve careful review.

Install only if you are comfortable with an agent running operational shell diagnostics against OpenClaw, Telegram, Feishu, WeChat, and cron. Before using repair modes, review every command, avoid printing raw config or Telegram update data, do not expose bot tokens in logs or chat, prefer native OpenClaw cron commands over full crontab replacement, and require explicit confirmation before sending test messages, changing configs, using sudo, or reinstalling crontab entries.

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)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/fix-crons.js:62
Finding

Global Crontab Replacement Exceeds the Required OpenClaw Scope

Content
View full analysis
/dev/null | sort | uniq -d # Find near-duplicates (same script, different schedule spacing by <5 min) crontab -l 2>/dev/null | grep -i "openclaw\\|morning-push" | sort If duplicates found: 1. Show user the duplicate lines 2. Confirm which to keep (usually the first one, or the one with the correct schedule) 3. Remove duplicates: # Export, edit, reimport crontab -l > /tmp/crontab_backup.txt # Edit /tmp/crontab_backup.txt to remove duplicate lines # Review the diff: diff /tmp/crontab_backup.txt <(sort -u /tmp/crontab_backup.txt) ⚠️ PAUSE: Show the diff output to the user and ask: "I'm about to replace your crontab with the deduplicated version above. The following lines will be removed: [list duplicate lines]. Do you confirm? (yes/no)" Only proceed after the user explicitly confirms. # Apply ONLY after explicit user confirmation: crontab /tmp/crontab_backup.txt # Verify: crontab -l | grep openclaw For openclaw native cron: openclaw cron remove ``` ### Technical Analysis The declared functionality is to inspect and repair OpenClaw-related scheduled tasks. However, the generated instructions run duplicate detection against the complete user crontab and subsequently replace that complete crontab. The global command: ```sh crontab -l | sort | uniq -d ``` does not restrict inspection to OpenClaw-managed records. More importantly, importing `/tmp/crontab_backup.txt` with `crontab` replaces every scheduled task belonging to the current user. A generic sorting or deduplication operation can also alter comments, environment assignments, ordering, and unrelated duplicate entries ...[truncated 1430 chars]
Remediation
View remediation
``` 2. Modify only entries carrying a validated OpenClaw marker. Do not use broad keywords such as `skill`, `morning-push`, or arbitrary command substrings as authorization to alter an entry. 3. Preserve every unrelated line byte-for-byte, including comments, blank lines, environment assignments, and ordering. 4. Create separate original and candidate files and display an exact unified diff: ```sh diff -u "$original" "$candidate" ``` 5. Reject the candidate if the diff contains any line not associated with a verified OpenClaw record. 6. Require explicit confirmation immediately before applying the candidate. 7. Prefer the native scoped interface: ```sh openclaw cron remove ``` when it can identify and remove a specific duplicate without replacing the complete crontab. 8. After applying the change, verify both that the intended duplicate was removed and that unrelated entries remain unchanged. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fix-crons.js:68
Finding

Predictable Temporary File Used to Store and Reinstall Crontab Content

Content
View full analysis
/tmp/crontab_backup.txt # Edit /tmp/crontab_backup.txt to remove duplicate lines # Review the diff: diff /tmp/crontab_backup.txt <(sort -u /tmp/crontab_backup.txt) ⚠️ PAUSE: Show the diff output to the user and ask: "I'm about to replace your crontab with the deduplicated version above. The following lines will be removed: [list duplicate lines]. Do you confirm? (yes/no)" Only proceed after the user explicitly confirms. # Apply ONLY after explicit user confirmation: crontab /tmp/crontab_backup.txt ``` ### Technical Analysis The instructions use the fixed path `/tmp/crontab_backup.txt`. Shared temporary directories are normally writable by other local users. A predictable pathname introduces several risks: - A pre-existing symbolic link can redirect the shell output to another file writable by the victim. - Another local process can replace or modify the file between export, review, and import. - Default permissions may allow other users to read cron commands and embedded credentials. - No ownership, file-type, permission, or integrity validation is performed before importing the file. - No cleanup is specified, leaving potentially sensitive data on disk. The most serious condition is the time-of-check/time-of-use interval between reviewing the file and running `crontab /tmp/crontab_backup.txt`. An attacker able to modify that file can inject arbitrary scheduled commands under the victim's account. ### Attack Path 1. A local attacker anticipates use of the documented fixed path. 2. The attacker creates a symlink at `/tmp/crontab_backup.txt` or waits for the victim to create the file. 3. The agent exports the victim's complete crontab to that path. 4. The attacker ...[truncated 987 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/check-wechat.js:25
Finding

WeChat Diagnostic Prints the Complete Configuration File

Content
View full analysis
/dev/null | python3 -m json.tool 2>/dev/null || echo "NO_CONFIG" ``` ### Technical Analysis The diagnostic needs only enough information to determine whether WeChat integration is configured and whether its bridge is operational. Instead, the command prints the complete JSON configuration. Configuration files may contain credentials, access tokens, cookies, session references, account identifiers, internal endpoints, or other operational metadata. Piping the file through `python3 -m json.tool` formats the complete object but performs no redaction. Because these commands are generated for execution by an AI agent, their output may enter model context, terminal logs, chat transcripts, health reports, or other persistent records. This increases exposure beyond the local configuration file's original access boundary. ### Attack Path 1. A user asks the agent to check the WeChat bridge. 2. The agent executes the generated configuration command. 3. The complete `~/.openclaw/wechat/config.json` content is printed. 4. The command output is incorporated into agent context, logs, or a diagnostic response. 5. Anyone with access to those secondary records may obtain sensitive configuration values. ### Impact Assessment The exact impact depends on the contents of the local configuration file. Potentially exposed information includes: - Authentication tokens or application secrets. - Account, tenant, or bridge identifiers. - Session-related references. - Internal service addresses. - Operational configuration useful for follow-on attacks. No evidence shows that the Skill transmits this information to an unknown remote server. The confirmed risk is unnecessary disclosure ...[truncated 58 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/check-telegram.js:51
Finding

Telegram Silence Check Exposes Raw Private Update Data and Bot Token in Process Arguments

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (64)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The description presents an operational self-diagnostic and repair skill. However, the code chunk is explicitly a 'PROMPT GENERATOR ONLY' script that uses console.log to emit human/agent instructions. It does not invoke lark-cli, curl, pgrep, crontab, openclaw, or any fix scripts; it only includes those commands as text in the output. It also does not create the referenced JSON report. Therefore the code's actual behavior is materially different from the declared purpose: it generates a diagnostic procedure rather than performing the diagnostic/repair itself.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a broad healthcheck and repair skill for multiple communication channels plus cron jobs. The provided code chunk is much narrower: it only outputs human/operator instructions for cron-task checking and possible follow-up actions. There is no implementation for Feishu, Telegram, or WeChat diagnostics, no direct system interrogation beyond printed commands, and no repair logic executed by this script. While cron-task checking is loosely aligned with part of the description, the overall declared purpose materially overstates the behavior of this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description presents a broad healthcheck-and-repair skill for multiple communication channels and scheduled tasks. However, this code chunk explicitly states it is a 'PROMPT GENERATOR ONLY — no outbound network requests' and simply outputs text telling a user/agent what commands to run to inspect Feishu status. It neither runs those commands nor repairs anything. It also contains no logic for Telegram, WeChat, or cron diagnostics. Therefore the actual behavior is materially narrower and different from the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a multi-channel openclaw healthcheck and repair capability spanning Feishu, Telegram, WeChat, and cron. The supplied code chunk only handles Telegram-related guidance, and even there it is explicitly a 'PROMPT GENERATOR ONLY' that prints shell commands/instructions rather than executing the diagnostic or repair actions itself. While Telegram silence/webhook/token issues are consistent with part of the description, the actual behavior is materially narrower in scope and capability than the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description presents a comprehensive healthcheck and repair skill for several communication systems and scheduled tasks. However, the supplied code chunk is narrowly scoped to WeChat and merely prints shell commands and interpretation guidance. It does not itself execute diagnostics, repair anything, or cover the other declared services (Feishu, Telegram, cron). This is a material description-behavior mismatch in both scope and capability.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description presents a broad healthcheck skill for multiple communication channels and scheduled tasks, including Feishu auth expiry, Telegram silence, WeChat bridge issues, and cron failures. The supplied code chunk is much narrower: it is a single script that prints step-by-step instructions for inspecting and repairing cron-related issues. It does include test-message verification examples for Feishu and Telegram, but these are only guidance snippets, not implemented diagnostics/repairs, and there is no WeChat handling at all. This is a material description-behavior mismatch because the declared primary purpose is comprehensive communications healthchecking, while the actual code is specifically a cron-fix prompt generator.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description presents a broad healthcheck/remediation skill for multiple communication systems and cron jobs. The supplied code chunk is narrowly scoped to Feishu authentication only. It is explicitly a 'PROMPT GENERATOR ONLY' and merely outputs step-by-step instructions for a human/agent to run lark-cli commands manually. There is no implemented self-diagnostic logic across channels, no direct checking of Telegram/WeChat/cron, and no automatic repair behavior. While Feishu auth repair is consistent with one part of the description, the overall declared purpose materially overstates the code’s scope and functionality.

Content

No source excerpt is available for this finding.

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · scripts/check-all.js (reported line 84)May include surrounding context.

js
��━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
STEP 4 — CRON TASKS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # List all openclaw cron entries (try openclaw native first, fallback to system cron)
  openclaw cron list 2>/dev/null || crontab -l 2>/dev/null | grep -i openclaw || echo "NO_CRON_FOUND"

  # Check for duplicates (same schedule + same command appearing more than once)
  crontab -l 2>/dev/null | sort | uniq -d | head -20

  # Check recent execution logs
  ls -lt ~/.openclaw/logs/*.log 2>/dev/null | head -10
  tail -20 ~/.openclaw/logs/cron.log 2>/dev/null || echo "NO_CRON_LOG"

For each cron entry found, determine:
  → Last run timestamp vs expected schedule — is it OVERDUE?
  → Same schedule + same script appearing 2+ times → DUPLICATE
  → Exit code in log is non-zero → FAILED
  → No log entry in t

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · scripts/check-crons.js (reported line 22)May include surrounding context.

js
*   node scripts/check-crons.js
 *   node scripts/check-crons.js --lang en
 */

const args = process.argv.slice(2);
const langIdx = args.indexOf('--lang');
const lang = langIdx !== -1 ? args[langIdx + 1] : 'zh';

if (lang === 'en') {
  console.log(`=== openclaw-healthcheck — Cron Task Check ===

Run the following checks:

  # List openclaw cron tasks
  openclaw cron list 2>/dev/null || \\
    crontab -l 2>/dev/null | grep -i "openclaw\\|morning-push\\|daily-push" | cat || \\
    echo "NO_CRON_FOUND"

  # Check for duplicates
  crontab -l 2>/dev/null | sort | uniq -d

  # Check recent logs
  tail -30 ~/.openclaw/logs/cron.log 2>/dev/null || echo "NO_CRON_LOG"

For each task found, assess:
  → Duplicate lines (same schedule + command)  → DUPLICATE → run fix-crons.js --dedup
  → Last run timestamp overdue by >1 interval  → MISSED    → run fix-crons.js --restart
  → Non-zero exit code in logs                 → FAILED    → check the failing script
  → Everything look

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · scripts/fix-crons.js (reported line 37)May include surrounding context.

js
��━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
STEP 1 — List all openclaw cron tasks
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Try openclaw native cron manager first
  openclaw cron list 2>/dev/null

  # Fallback: read system crontab filtered to openclaw
  crontab -l 2>/dev/null | grep -i "openclaw\\|morning-push\\|daily-push\\|skill" | cat

  # Also check openclaw-specific cron config files
  ls ~/.openclaw/cron/ 2>/dev/null
  cat ~/.openclaw/cron/*.json 2>/dev/null | python3 -m json.tool 2>/dev/null

  For each task found, record:
    - Task ID / name
    - Schedule (cron expression)
    - Target channel (feishu / telegram / wechat)
    - Script or command being run
    - Last run timestamp (from logs if available)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━�

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/fix-crons.js (reported line 100)May include surrounding context.

js
If cron daemon is not running:
    # macOS:
    launchctl start com.vix.cron 2>/dev/null || sudo launchctl start com.vix.cron

  If openclaw push daemon is not running:
    openclaw push-on 2>/dev/null || openclaw cron restart 2>/dev/null

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/fix-crons.js (reported line 211)May include surrounding context.

js
If cron daemon is not running:
    # macOS:
    launchctl start com.vix.cron 2>/dev/null || sudo launchctl start com.vix.cron

  If openclaw push daemon is not running:
    openclaw push-on 2>/dev/null || openclaw cron restart 2>/dev/null

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares operational requirements and describes behavior involving environment variables, shell commands, file writes, and outbound network interactions, but it does not define any explicit tool or permission scope. In an agent setting, that mismatch can cause overbroad execution authority or make reviewers/users unaware that the skill may access secrets, modify cron state, or send external messages.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill advertises test pushes, reauthentication flows, and cron deduplication/repair without an explicit safety warning or confirmation gate for actions that can send external messages or modify system scheduling. In agent-driven environments, that can lead to unintended outbound notifications, configuration drift, or service disruption from automatic cron edits.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file header explicitly claims the script is a 'PROMPT GENERATOR ONLY — no outbound network requests,' but the generated prompt instructs the agent to run curl commands against the Telegram Bot API. That mismatch is dangerous because it can bypass user/operator expectations and security controls that rely on truthful disclosure of network behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script sets lang to 'zh' when the user does not provide --lang, which forces a specific language choice by default. The file only offers English as an explicit override and does not indicate user consent for the default locale, which is a natural-language policy concern.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

The generated diagnostic instructs the agent to send the TELEGRAM_BOT_TOKEN in a request URL to api.telegram.org. Even though this is intended as a health check, it causes external transmission of a live credential and account metadata, which may violate least-privilege or no-network expectations in an agent skill.

Content

Scanner excerpt · scripts/check-all.js (reported line 49)May include surrounding context.

js
test -n "$TELEGRAM_BOT_TOKEN" && echo "TOKEN_SET" || echo "TOKEN_MISSING"

  # Test bot API reachability
  curl -s --max-time 10 "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/getMe" | \\
    python3 -c "import sys,json; d=json.load(sys.stdin); print('OK:', d['result']['username'])" \\
    2>/dev/null || echo "API_UNREACHABLE"

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

This instruction performs another outbound Telegram API call using the bot token to fetch updates, expanding external data transmission beyond a minimal liveness check. It increases exposure by retrieving message/update metadata and may leak sensitive operational information if executed in a monitored or logged environment.

Content

Scanner excerpt · scripts/check-all.js (reported line 54)May include surrounding context.

js
2>/dev/null || echo "API_UNREACHABLE"

  # Check for recent updates (silence = possible webhook issue)
  curl -s --max-time 10 "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/getUpdates?limit=1" | \\
    python3 -c "import sys,json; d=json.load(sys.stdin); print('UPDATES:', len(d['result']))" \\
    2>/dev/null

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

The Chinese variant duplicates the same outbound Telegram credential-bearing request as the English path. This remains security-relevant because the script can direct an agent to contact an external service despite the top-level claim of no outbound requests.

Content

Scanner excerpt · scripts/check-all.js (reported line 153)May include surrounding context.

js
test -n "$TELEGRAM_BOT_TOKEN" && echo "TOKEN_SET" || echo "TOKEN_MISSING"

  # 测试 Bot API 可达性
  curl -s --max-time 10 "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/getMe" | \\
    python3 -c "import sys,json; d=json.load(sys.stdin); print('OK:', d['result']['username'])" \\
    2>/dev/null || echo "API_UNREACHABLE"

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

The Chinese prompt also instructs the agent to call getUpdates on Telegram, which transmits credentials and fetches account/update data externally. In an agent-skill context, duplicated behavior across language branches increases the chance that the risky path is executed unexpectedly.

Content

Scanner excerpt · scripts/check-all.js (reported line 158)May include surrounding context.

js
2>/dev/null || echo "API_UNREACHABLE"

  # 检查最近更新(静默可能是 webhook 断开)
  curl -s --max-time 10 "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/getUpdates?limit=1" | \\
    python3 -c "import sys,json; d=json.load(sys.stdin); print('UPDATES:', len(d['result']))" \\
    2>/dev/null

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The header says this is a "PROMPT GENERATOR ONLY — no outbound network requests," but the emitted diagnostic steps include openclaw cron list at L21/L47. That command is not shown as a purely local operation and could reasonably query a remote openclaw service, so the documentation overstates the script's non-network nature.

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 · scripts/check-all.js (reported line 84)May include surrounding context.

js
# List openclaw cron tasks
  openclaw cron list 2>/dev/null || \\
    crontab -l 2>/dev/null | grep -i "openclaw\\|morning-push\\|daily-push" | cat || \\
    echo "NO_CRON_FOUND"

  # Check for duplicates

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 · scripts/check-all.js (reported line 87)May include surrounding context.

js
# List openclaw cron tasks
  openclaw cron list 2>/dev/null || \\
    crontab -l 2>/dev/null | grep -i "openclaw\\|morning-push\\|daily-push" | cat || \\
    echo "NO_CRON_FOUND"

  # Check for duplicates

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 · scripts/check-all.js (reported line 188)May include surrounding context.

js
# List openclaw cron tasks
  openclaw cron list 2>/dev/null || \\
    crontab -l 2>/dev/null | grep -i "openclaw\\|morning-push\\|daily-push" | cat || \\
    echo "NO_CRON_FOUND"

  # Check for duplicates

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 · scripts/check-all.js (reported line 191)May include surrounding context.

js
# List openclaw cron tasks
  openclaw cron list 2>/dev/null || \\
    crontab -l 2>/dev/null | grep -i "openclaw\\|morning-push\\|daily-push" | cat || \\
    echo "NO_CRON_FOUND"

  # Check for duplicates

Static analysis

No suspicious patterns detected.