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

Content
View full analysis

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
View 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.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
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).

Content

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

Remove to re-enable:

bash
rm ~/.openclaw/skills/desktop-guardian/KILL_SWITCH

Graceful Degradation

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
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

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/policies.md (reported line 72)May include surrounding context.

md
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

Memory Manipulation

High
Category
Memory Poisoning
Confidence
90% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

Scanner excerpt · scripts/helpers.py (reported line 520)May include surrounding context.

python
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

Undeclared Tool Scope

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.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · scripts/install.sh (reported line 157)May include surrounding context.

sh
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)"

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · scripts/install.sh (reported line 181)May include surrounding context.

sh
# --- 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">

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · scripts/install.sh (reported line 183)May include surrounding context.

sh
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>

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · scripts/install.sh (reported line 183)May include surrounding context.

sh
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>

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · scripts/install.sh (reported line 185)May include surrounding context.

sh
<?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>

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · scripts/install.sh (reported line 206)May include surrounding context.

sh
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
    </dict>
</dict>
</plist>
EOF
chmod 644 "$LAUNCH_AGENT_PLIST"

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · scripts/install.sh (reported line 208)May include surrounding context.

sh
</dict>
</plist>
EOF
chmod 644 "$LAUNCH_AGENT_PLIST"

# Bootstrap
launchctl bootout "gui/$(id -u)/$LAUNCH_AGENT_LABEL" 2>/dev/null || true

Static analysis

No suspicious patterns detected.