Back to skill

Security audit

Desktop Guardian

Security checks for vulnerabilities and agentic risk

Overview

This skill is not clearly malicious, but it installs and configures an always-on Mac desktop controller that can close apps, close browser tabs, and dismiss dialogs automatically.

Install only if you want an always-on Mac desktop automation agent. Review and edit policy.yaml before enabling it, especially cleanup.enabled, cleanup.apps.action, browser tab/window actions, and dialogs.auto_dismiss. Consider disabling persistence or running manually first, and be aware that the installer may modify Hammerspoon configuration and install unpinned dependencies.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T08 · Insecure Dependencies

Warning
Location
scripts/install.sh:29
Finding
Unpinned PyPI Dependency Installation## Vulnerability Details **File Location**: `scripts/install.sh:29-34` **Vulnerability Type**: Unpinned third-party dependency installation **Risk Level**: Medium ```bash if python3 -c "import yaml" 2>/dev/null; then info "PyYAML already installed" else echo "Installing PyYAML..." pip3 install --user pyyaml info "PyYAML installed" fi ``` ### Technical Analysis The installation script retrieves and installs the latest available `pyyaml` package without a version constraint, cryptographic hash verification, lock file, or isolated virtual environment. This makes the installed code dependent on mutable upstream package-index state rather than the reviewed project contents. Python package installation may execute package build or installation code with the privileges of the user running the installer. A compromised upstream release, package-index compromise, or index redirection could therefore cause arbitrary code execution even though the project itself contains no confirmed malicious payload. ### Attack Path 1. An attacker compromises the upstream package, its publishing credentials, or the configured Python package index. 2. The attacker publishes or serves a malicious `pyyaml` distribution. 3. A user without an importable `yaml` module runs `bash scripts/install.sh`. 4. The script executes `pip3 install --user pyyaml` without pinning or hash verification. 5. `pip` downloads the attacker-controlled distribution and executes any applicable build or installation logic. 6. The malicious code runs with the installing user's privileges and may establish additional persistence, modify user files, or access user-session data. ### Impact Assessment Successful exploitation provides arbitrary code execution as the user who runs the installer. This may expose files readable by that user, browser and application data accessible within the user session, OpenClaw configuration, shell configuration, and other user-owned resources. The command does not i ...[truncated 123 chars]
Remediation
## Remediation Suggestions - Pin PyYAML to a specifically reviewed version instead of installing the latest release. - Maintain a requirements lock file containing cryptographic hashes and install with `pip --require-hashes`. - Use an isolated virtual environment rather than modifying the user's package environment. - Prefer binary wheels from a trusted index where practical, and explicitly configure the approved package index. - Ensure installation fails closed if the dependency cannot be verified. - Periodically review and deliberately update the pinned version after security testing. Example hardened workflow: ```bash python3 -m venv "$CONFIG_DIR/venv" "$CONFIG_DIR/venv/bin/python" -m pip install \ --require-hashes \ --only-binary=:all: \ -r "$PROJECT_DIR/requirements.lock" ``` The corresponding `requirements.lock` should pin the exact PyYAML version and list approved SHA-256 hashes for every supported artifact.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (50)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented behavior extends beyond passive desktop monitoring into installation, persistence setup, and uninstallation/removal of local components, but those side effects are not clearly reflected in the declared purpose. This mismatch can cause agents or users to trust the skill for routine GUI tasks while it also modifies startup behavior and local files, increasing the risk of unintended persistence or destructive cleanup actions.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
Remove to re-enable:
```bash
rm ~/.openclaw/skills/desktop-guardian/KILL_SWITCH
```

## Graceful Degradation
Confidence
85% 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).

Credential Access

High
Category
Privilege Escalation
Content
Allow, Delete, Remove, Erase, Format, Grant, Always Allow, Install, Authenticate, Permit, Trust

**App blacklist** — never auto-dismissed:
SecurityAgent, Keychain Access, System Settings, Disk Utility

**Protected apps** — never closed:
Finder, loginwindow, WindowServer, SystemUIServer, Dock, Spotlight, Hammerspoon
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
Allow, Delete, Remove, Erase, Format, Grant, Always Allow, Install, Authenticate, Permit, Trust

**App blacklist** — never auto-dismissed:
SecurityAgent, Keychain Access, System Settings, Disk Utility

**Protected apps** — never closed:
Finder, loginwindow, WindowServer, SystemUIServer, Dock, Spotlight, Hammerspoon
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Memory Manipulation

High
Category
Memory Poisoning
Content
raise ValueError("state is not a dict")
            return data
        except (json.JSONDecodeError, ValueError) as e:
            print(f"WARNING: corrupt state.json, resetting to defaults: {e}", file=sys.stderr)
            default = _default_state()
            _save_state(default)
            return default
Confidence
90% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill advertises and instructs installation of functionality that can write files, install components, edit Hammerspoon configuration, and run shell commands, yet it declares no explicit tool scope or permission boundaries. In a skill with full desktop automation and persistent monitoring, missing scope declarations materially increase the chance that an agent invokes powerful side effects without informed consent or policy enforcement.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The invocation guidance is extremely broad, effectively inviting use for nearly any macOS GUI interaction or desktop monitoring task. For a skill with full accessibility-driven control, broad matching increases the probability of accidental invocation in contexts where closing apps, sending keypresses, or dismissing dialogs would be unsafe or out of scope.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill describes autonomous closure of apps/windows and dismissal of dialogs without prominent warnings about false positives, data loss, interrupted workflows, or suppression of important security prompts. In the context of an always-on desktop guardian with Accessibility access, such automation can silently interfere with user actions or conceal security-relevant system messages.

Vague Triggers

Medium
Confidence
91% confidence
Finding
Cleanup is enabled and configured to close apps, browser windows, and tabs, but this example file does not define clear activation boundaries, approval requirements, or contextual safeguards. In a desktop-control skill with broad GUI authority, ambiguous automatic cleanup behavior can cause unintended disruptive actions, data loss from unsaved work, or termination of user-approved applications.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The configuration automatically closes apps, browser windows, and tabs with no visible user-facing warning or confirmation mechanism in this file. Because this skill is explicitly designed for full macOS desktop control, silent destructive actions are more dangerous here: they can interfere with normal user activity, hide evidence of agent actions, or cause loss of unsaved work.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
Automatic dialog dismissal is enabled, including for system-facing agents such as UserNotificationCenter and with a default click strategy, while only some prompts are routed to ask-before-dismiss. In the context of a skill that continuously monitors and controls the macOS desktop, this can suppress security-relevant prompts, permission notices, errors, or recovery dialogs, reducing user awareness and potentially bypassing important human decisions.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The policy guide documents automatic closure of non-whitelisted apps, browser windows, and tabs without an explicit warning that these actions can terminate user workflows or cause unsaved data loss. In a skill whose purpose is full desktop control and automated cleanup, normalizing destructive actions without prominent safeguards increases the chance that operators deploy risky policies without understanding the consequences.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The guide describes auto-dismissing dialogs, including system-originated prompts, without a clear warning that dismissing security or integrity-related dialogs can hide important consent, malware, download, or system state information from the user. Given this skill's always-on monitoring and automation of the macOS GUI, poorly understood dialog dismissal policies could suppress signals that should require human review.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The script collects and outputs a detailed inventory of running GUI applications, visible window titles/IDs, frontmost application state, and detected dialog metadata without any user-facing notice or consent gate. In the context of a desktop-control skill that already has broad GUI automation capability, this materially increases surveillance and privacy risk because sensitive app names, document titles, websites, or security prompts may be exposed to downstream consumers of the JSON output.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The code generates autonomous close and force-close actions for any app not on the whitelist, with no mandatory confirmation gate or runtime safety interlock. In a skill explicitly designed for desktop control, this can terminate user applications unexpectedly, causing denial of service and potential data loss if unsaved work is present.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The helper can auto-dismiss dialogs by clicking the default button or sending Escape based only on the dialog's owning app, without validating the dialog's semantic meaning. On macOS, default buttons on permission, security, or destructive prompts may authorize actions, suppress safeguards, or discard data, making silent dismissal particularly risky in a GUI automation skill.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script creates and appends to ~/.hammerspoon/init.lua, altering the user's Hammerspoon configuration. Although it logs that hs.ipc was added after the fact, there is no prior warning or confirmation before modifying this existing user config file.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
chmod 700 "$CONFIG_DIR"
if [[ ! -f "$CONFIG_DIR/policy.yaml" ]]; then
    cp "$PROJECT_DIR/assets/config.example.yaml" "$CONFIG_DIR/policy.yaml"
    chmod 600 "$CONFIG_DIR/policy.yaml"
    info "Default policy.yaml created"
else
    info "policy.yaml already exists (preserved)"
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The script unconditionally writes and bootstraps a LaunchAgent, creating persistent background execution every 60 seconds without an explicit opt-in prompt immediately before installation. Persistence is a sensitive action, and in the context of a desktop-control skill with Accessibility-related capabilities, silent installation materially increases risk if the component is later abused or misconfigured.

Session Persistence

Medium
Category
Rogue Agent
Content
# --- Install LaunchAgent ---
step "Installing LaunchAgent"
cat > "$LAUNCH_AGENT_PLIST" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
Confidence
86% confidence
Finding
Beginning creation of a user LaunchAgent plist is part of establishing login/session persistence for a background monitor. In a skill that advertises always-on desktop monitoring and automated interaction with dialogs, persistence meaningfully expands the blast radius of any future compromise or policy mistake.

Session Persistence

Medium
Category
Rogue Agent
Content
step "Installing LaunchAgent"
cat > "$LAUNCH_AGENT_PLIST" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
Confidence
84% confidence
Finding
This duplicate hit is part of the same persistence mechanism: a LaunchAgent definition for recurring execution. In this context, persistence is more sensitive because the skill is designed to monitor and control the GUI continuously.

Session Persistence

Medium
Category
Rogue Agent
Content
step "Installing LaunchAgent"
cat > "$LAUNCH_AGENT_PLIST" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
Confidence
84% confidence
Finding
This duplicate hit is part of the same persistence mechanism: a LaunchAgent definition for recurring execution. In this context, persistence is more sensitive because the skill is designed to monitor and control the GUI continuously.

Session Persistence

Medium
Category
Rogue Agent
Content
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>${LAUNCH_AGENT_LABEL}</string>
Confidence
84% confidence
Finding
The plist declaration continues the same autostart mechanism. Persistent background execution is not inherently malicious, but it is security-relevant and should be treated carefully for a tool with Accessibility and desktop automation scope.

Session Persistence

Medium
Category
Rogue Agent
Content
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
    </dict>
</dict>
</plist>
EOF
chmod 644 "$LAUNCH_AGENT_PLIST"
Confidence
83% confidence
Finding
This line is still within the created plist and therefore part of the persistence artifact. Combined with the monitor script path and StartInterval, it supports ongoing automatic execution within the user session.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
</dict>
</plist>
EOF
chmod 644 "$LAUNCH_AGENT_PLIST"

# Bootstrap
launchctl bootout "gui/$(id -u)/$LAUNCH_AGENT_LABEL" 2>/dev/null || true
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Static analysis

No suspicious patterns detected.