Back to skill

Security audit

Mac Cleaner

Security checks for vulnerabilities and agentic risk

Overview

This Mac cleanup skill is mostly aligned with its stated purpose, but its promised dry-run preview actually performs deletion and it adds persistent ways to trigger cleanup.

Review this carefully before installing. The main risk is that the advertised dry run is not safe: running the documented preview command can delete files immediately. Do not enable the cron job or use the dashboard Run Now endpoint unless the dry-run implementation, authentication/authorization, and restart command are fixed.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:1148
Finding

Mandatory Dry Run Performs Real Destructive Cleanup

Content
View full analysis
sum + i.size_mb, 0); const totalBytes = Math.round(totalMb * 1024 * 1024); const report = { timestamp: new Date().toISOString(), bytes_freed: totalBytes, items_cleaned: items, errors, duration_ms: durationMs, }; fs.mkdirSync(DATA_DIR, { recursive: true }); fs.writeFileSync(LAST_RUN_FILE, JSON.stringify(report, null, 2)); appendHistory(report); const totalGb = (totalMb / 1024).toFixed(2); const summary = `Freed ${totalGb} GB across ${items.length} items in ${(durationMs / 1000).toFixed(1)}s`; writeStatus(errors.length > 0 ? "error" : "ok", summary); console.log(`[mac-cleaner] ${summary}`); if (errors.length > 0) { console.log(`[mac-cleaner] ${errors.length} errors encountered`); } console.log(`[mac-cleaner] Report written to ${LAST_RUN_FILE}`); } main(); ``` The installation instructions nevertheless describe this invocation as a safe preview: ```markdown ### Step 11 -- Mandatory Dry Run (Preview Before Deleting) **ALWAYS run dry-run first.** Show the user what will be cleaned before anything is deleted. **EXEC ...[truncated 2476 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:1053
Finding

Destructive Cleanup API Lacks Authentication and Request Authorization

Content
View full analysis
( (resolve, reject) => { exec( AGENT_SCRIPT, { timeout: 300000, maxBuffer: 10 * 1024 * 1024 }, (error, stdout, stderr) => { if (error) { reject(error); } else { resolve({ stdout, stderr }); } } ); } ); return NextResponse.json({ success: true, output: result.stdout, stderr: result.stderr, }); } catch (error) { console.error("[/api/mac-cleaner/run] Error:", error); return NextResponse.json( { success: false, error: "Cleanup failed", details: error instanceof Error ? error.message : String(error), }, { status: 500 } ); } } ``` ### Technical Analysis The route treats possession of network access to `/api/mac-cleaner/run` as sufficient authority to start a destructive cleanup. It does not verify: - An authenticated Mission Control user - Whether the caller owns or administers the installation - A CSRF token - The HTTP `Origin` or `Referer` - A recent user-approved cleanup preview - Whether another cleanup is already running The endpoint executes with ...[truncated 1758 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:1175
Finding

Dashboard Rebuild Uses Overbroad Forced Process Termination

Content
View full analysis
/dev/null; pkill -f "next.*mission-control" 2>/dev/null; sleep 1; kill -9 $(pgrep -f "next.*mission-control") 2>/dev/null; rm -rf ~/.openclaw/workspace/mission-control/.next; launchctl load ~/Library/LaunchAgents/ai.openclaw.mission-control.plist && echo "plist loaded" ``` ### Technical Analysis The rebuild command identifies processes by a broad regular expression applied to complete command lines: ```bash next.*mission-control ``` This is not a reliable service-identity check. Any process whose command line contains `next`, followed later by `mission-control`, can match, including unrelated development servers, scripts, or user processes. The command first uses `pkill` and then applies unconditional `SIGKILL` to all remaining matches. `SIGKILL` prevents graceful shutdown, cleanup handlers, buffered writes, and orderly release of resources. This exceeds the permissions and process scope necessary to rebuild one dashboard managed by a known LaunchAgent. Command substitution also provides weak failure handling. If process state changes between `pgrep` and `kill`, different or stale targets may be affected. The command does not verify that matched PIDs belong to the expected LaunchAgent before terminating them. ### Attack Path 1. The Skill reaches the mandatory Mission Control rebuild step. 2. One or more unrelated user processes have command lines matching `next.*mission-control`. 3. `pkill -f` sends a termination signal to every matching process. 4. After one second, `pgrep -f` enumerates remaining matches. 5. `kill -9` forcibly terminates every returned PID without verifying service identity. 6. The affected processes cannot perform graceful shutdown and may lose in-progress w ...[truncated 846 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (17)

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger phrases are broad enough to match ordinary requests like 'free up disk space' or 'I'm running out of space,' causing the skill to activate in situations where the user may only want advice rather than destructive automation. In this skill's context, accidental activation is especially risky because it writes files, modifies Mission Control, and may delete data immediately.

Content

No source excerpt is available for this finding.

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

md
| Runtime required | Node.js v14+ (built-ins only -- no npm install needed) |
| Optional system tools | `npm` (cache cleanup, skipped if absent), `brew` (Homebrew cleanup, skipped if absent) |
| Targets | `~/Library/Caches`, `~/Library/Logs`, `~/.Trash`, `~/.npm/_cacache`, Homebrew cache, `~/.next` build artifacts, and system-generated Unicode-slash orphan folders in `~` -- never source code, documents, databases, or user data |
| Sudo required | No -- runs as current user |
| Logging | Every deletion logged to `data/last-run.json` with path, size, reason |
| Tools used | Node.js `fs`, `child_process`; `brew cleanup` (optional), `npm cache clean --force` (optional), `df`, `du` |
| Dry-run mode | Pass `--dry-run` to preview what would be cleaned without deleting anything |

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The safety profile advertises that passing --dry-run will preview cleanup without deleting anything, but the cleanup code does not check process.argv for this flag and always performs deletion actions. This is dangerous because it creates a false safety assurance around destructive operations on caches, logs, trash, and other directories.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill mandates a dry-run preview and explicit confirmation before deletion, but the provided cleanup script contains no implementation for a --dry-run mode or preview.json output. This means users may be told they are seeing a harmless preview while the script either ignores the flag or proceeds with destructive cleanup logic, undermining informed consent for file deletion.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documented flow claims users will see a preview and confirm before deletion, but the implementation does not support that preview behavior. This weakens the quality and reliability of the consent barrier, making destructive actions more likely to occur without the warning users were promised.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

The skill instructs execution of rm -rf against the Mission Control build directory as part of a chained shell command. Recursive forced deletion is dangerous because path mistakes, environment expansion issues, or reuse in a different context can irreversibly remove data without validation or rollback.

Content

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

EXECUTE using Bash tool:

bash
launchctl unload ~/Library/LaunchAgents/ai.openclaw.mission-control.plist 2>/dev/null; pkill -f "next.*mission-control" 2>/dev/null; sleep 1; kill -9 $(pgrep -f "next.*mission-control") 2>/dev/null; rm -rf ~/.openclaw/workspace/mission-control/.next; launchctl load ~/Library/LaunchAgents/ai.openclaw.mission-control.plist && echo "plist loaded"

Wait 20 seconds, then verify:

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

The skill instructs execution of rm -rf against the Mission Control build directory as part of a chained shell command. Recursive forced deletion is dangerous because path mistakes, environment expansion issues, or reuse in a different context can irreversibly remove data without validation or rollback.

Content

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

EXECUTE using Bash tool:

bash
launchctl unload ~/Library/LaunchAgents/ai.openclaw.mission-control.plist 2>/dev/null; pkill -f "next.*mission-control" 2>/dev/null; sleep 1; kill -9 $(pgrep -f "next.*mission-control") 2>/dev/null; rm -rf ~/.openclaw/workspace/mission-control/.next; launchctl load ~/Library/LaunchAgents/ai.openclaw.mission-control.plist && echo "plist loaded"

Wait 20 seconds, then verify:

Chaining Abuse

High
Category
Tool Misuse
Confidence
96% confidence
Finding

The rebuild instruction chains multiple powerful commands with semicolons, including process killing, directory deletion, and LaunchAgent loading. Chained shell execution reduces error isolation and makes it easy for one mistaken invocation to perform several state-changing operations in sequence, complicating review and recovery.

Content

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

EXECUTE using Bash tool:

bash
launchctl unload ~/Library/LaunchAgents/ai.openclaw.mission-control.plist 2>/dev/null; pkill -f "next.*mission-control" 2>/dev/null; sleep 1; kill -9 $(pgrep -f "next.*mission-control") 2>/dev/null; rm -rf ~/.openclaw/workspace/mission-control/.next; launchctl load ~/Library/LaunchAgents/ai.openclaw.mission-control.plist && echo "plist loaded"

Wait 20 seconds, then verify:

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest description states the skill 'Installs a Mission Control dashboard and a Sunday 3 AM cron job on first run.' Later installation instructions explicitly say the cron job should only be registered with explicit user consent and skipped otherwise. These statements conflict about whether scheduling is automatic or conditional.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
| Runtime required | Node.js v14+ (built-ins only -- no npm install needed) |
| Optional system tools | `npm` (cache cleanup, skipped if absent), `brew` (Homebrew cleanup, skipped if absent) |
| Targets | `~/Library/Caches`, `~/Library/Logs`, `~/.Trash`, `~/.npm/_cacache`, Homebrew cache, `~/.next` build artifacts, and system-generated Unicode-slash orphan folders in `~` -- never source code, documents, databases, or user data |
| Sudo required | No -- runs as current user |
| Logging | Every deletion logged to `data/last-run.json` with path, size, reason |
| Tools used | Node.js `fs`, `child_process`; `brew cleanup` (optional), `npm cache clean --force` (optional), `df`, `du` |
| Dry-run mode | Pass `--dry-run` to preview what would be cleaned without deleting anything |

Session Persistence

Medium
Category
Rogue Agent
Confidence
91% confidence
Finding

The skill installs persistent artifacts under ~/.openclaw/workspace/agents/mac-cleaner and modifies the local environment beyond the current session. Persistence is security-relevant here because broad triggers and misleading dry-run claims can cause lasting changes even when the user did not intend a permanent installation.

Content

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

md
## Installation Steps

**Before starting**: Inform the user that this skill will:
1. Create an agent directory at `~/.openclaw/workspace/agents/mac-cleaner/` and write Node.js scripts there
2. Add a Mission Control dashboard page (read-only UI)
3. Optionally register a weekly cron job (Step 10 -- only with explicit user consent)

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

Writing src/index.js into a persistent agent directory establishes executable code that can be rerun later, which is a form of local persistence. In context, this is more dangerous because the skill also wires the script into API routes and optional scheduling, increasing the chance of recurring destructive behavior.

Content

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

module.exports = { writeStatus };

text

### Step 3 -- Write `src/index.js`

Write this file to `~/.openclaw/workspace/agents/mac-cleaner/src/index.js`:

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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 · SKILL.md (reported line 452)May include surrounding context.

md
duration_ms: durationMs,
  };

  // Write report
  fs.mkdirSync(DATA_DIR, { recursive: true });
  fs.writeFileSync(LAST_RUN_FILE, JSON.stringify(report, null, 2));

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

Creating a new persistent API route in Mission Control exposes the agent's data and execution surface beyond the current interaction. This increases risk because it enables later triggering and visibility of filesystem activity through a standing web interface.

Content

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

}

text

### Step 6 -- Create API Route (GET)

Write this file to `~/.openclaw/workspace/mission-control/app/api/mac-cleaner/route.ts`:

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The cron job hard-codes the timezone to Asia/Singapore, which can cause scheduled execution at unexpected local times for most users. For a destructive maintenance task, timing surprises materially increase risk because cleanup could occur while the user is actively working or when they did not intend it to run.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
93% confidence
Finding

Loading a LaunchAgent is a persistence mechanism because it alters ongoing service state on the machine. In this context, coupling cleanup installation with service restart behavior expands the blast radius of a mistaken or overly broad skill invocation.

Content

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

EXECUTE using Bash tool:

bash
launchctl unload ~/Library/LaunchAgents/ai.openclaw.mission-control.plist 2>/dev/null; pkill -f "next.*mission-control" 2>/dev/null; sleep 1; kill -9 $(pgrep -f "next.*mission-control") 2>/dev/null; rm -rf ~/.openclaw/workspace/mission-control/.next; launchctl load ~/Library/LaunchAgents/ai.openclaw.mission-control.plist && echo "plist loaded"

Wait 20 seconds, then verify:

Session Persistence

Medium
Category
Rogue Agent
Confidence
93% confidence
Finding

Loading a LaunchAgent is a persistence mechanism because it alters ongoing service state on the machine. In this context, coupling cleanup installation with service restart behavior expands the blast radius of a mistaken or overly broad skill invocation.

Content

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

EXECUTE using Bash tool:

bash
launchctl unload ~/Library/LaunchAgents/ai.openclaw.mission-control.plist 2>/dev/null; pkill -f "next.*mission-control" 2>/dev/null; sleep 1; kill -9 $(pgrep -f "next.*mission-control") 2>/dev/null; rm -rf ~/.openclaw/workspace/mission-control/.next; launchctl load ~/Library/LaunchAgents/ai.openclaw.mission-control.plist && echo "plist loaded"

Wait 20 seconds, then verify:

Static analysis

Detected: suspicious.destructive_delete_command

Documentation contains a destructive delete command without an explicit confirmation gate.

Warn
Code
suspicious.destructive_delete_command
Location
SKILL.md:1175