Back to skill

Security audit

OpenClaw Desktop Control

Security checks for vulnerabilities and agentic risk

Overview

This desktop automation skill is mostly coherent, but it gives broad control over the local desktop and unrestricted file read/write access without clear safeguards.

Install only if you intentionally want an agent to control your active desktop, capture screenshots, type into applications, open or close apps, and read or write local files as your user. Prefer using it in a VM or test account, avoid sensitive windows and secrets while it is active, and review automation scripts before running them.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (42)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented behavior does not fully match the advertised purpose: it includes file system read/write actions not disclosed in the description, and claims VNC/RDP support that appears unsubstantiated. In a remote desktop automation context, mismatched documentation is dangerous because users may authorize a skill for UI automation while overlooking that it can also modify files or rely on misleading transport assumptions.

Missing User Warnings

High
Confidence
96% confidence
Finding
The file read/write commands permit direct access to local files without any warning, approval workflow, or path limitation, making sensitive data theft and destructive modification straightforward. In this skill context, that is more dangerous because users may expect UI automation, not unrestricted filesystem access.

Missing User Warnings

High
Confidence
91% confidence
Finding
Automation script execution can chain together arbitrary desktop actions at scale, including clicks, keystrokes, waits, and likely file interactions through the controller, without any user warning or safety validation. This increases the chance of stealthy destructive behavior, bulk data exfiltration, or unintended irreversible UI actions.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill declares broad tools (`read`, `write`, `exec`) but does not define any narrower tool scope such as `permissions` or `allowed-tools`, while the documentation clearly enables shell execution and file read/write operations. In a desktop-control skill, this increases risk because the capability set can be used to manipulate the host system and access sensitive data beyond what a user may infer from the metadata.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Ubuntu/Debian
sudo apt-get install python3-pil python3-xlib scrot

# macOS
brew install pillow
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The screenshot and `--base64` examples explicitly support AI analysis of desktop captures, but the documentation does not clearly warn that screenshots can contain passwords, tokens, personal data, or regulated information. In a desktop-control skill this is especially sensitive because whole-screen capture can silently exfiltrate far more information than a typical file read.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The automation and file-write functionality can perform destructive or unintended actions on a desktop or filesystem, yet the documentation lacks a clear warning about operational safety, confirmation requirements, or rollback considerations. Because this skill can drive mouse, keyboard, apps, and file writes, accidental or malicious misuse could cause data loss, unsafe system changes, or unauthorized actions under the current user's privileges.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The file’s human-readable instructions and comments are entirely in Chinese, which imposes a specific language on users without any opt-in or explanation. Under the policy, language-specific guidance is only acceptable when the skill offers a choice or clearly documents a justified regional constraint.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The script performs real mouse and keyboard automation to launch a terminal and start a text editor without any user confirmation, safety interlock, or environment validation. In a desktop-control skill, such actions can unexpectedly interfere with the user session, trigger unintended commands, or be repurposed for harmful local actions if the script is modified or run in the wrong context.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The controller exposes arbitrary file read and write primitives that are unrelated to merely controlling the desktop UI. In the context of a desktop automation skill, this materially broadens access to local data and persistence, enabling exfiltration of sensitive files or tampering with user content without any scope restriction.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
x, y, w, h = region
            cmd = ['screencapture', '-x', '-R', f'{x},{y},{w},{h}', temp_path]

        subprocess.run(cmd, check=True)
        data = Path(temp_path).read_bytes()
        Path(temp_path).unlink()
        return data
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
cmd = ['gnome-screenshot', '-f', temp_path]

        try:
            subprocess.run(cmd, check=True, capture_output=True)
        except (subprocess.CalledProcessError, FileNotFoundError):
            # Fallback to scrot
            if region:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
cmd = ['gnome-screenshot', '-f', temp_path]

        try:
            subprocess.run(cmd, check=True, capture_output=True)
        except (subprocess.CalledProcessError, FileNotFoundError):
            # Fallback to scrot
            if region:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill performs screenshots, keyboard injection, mouse control, window activation, and app launch without any user-facing disclosure or runtime confirmation. Because the skill operates on the local desktop, silent execution significantly raises the chance of unauthorized actions, privacy exposure, and covert manipulation of the host session.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def mouse_move(self, x: int, y: int) -> None:
        """Move mouse to coordinates"""
        if self.platform == 'macos':
            subprocess.run(['cliclick', 'm:', f'{x},{y}'], check=False)
        elif self.platform == 'linux':
            subprocess.run(['xdotool', 'mousemove', str(x), str(y)], check=False)
        else:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if self.platform == 'macos':
            subprocess.run(['cliclick', 'm:', f'{x},{y}'], check=False)
        elif self.platform == 'linux':
            subprocess.run(['xdotool', 'mousemove', str(x), str(y)], check=False)
        else:
            # Windows - would need pyautogui or similar
            pass
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if self.platform == 'macos':
            btn = 'cl' if button == 'left' else 'cr'
            for _ in range(clicks):
                subprocess.run(['cliclick', btn], check=False)
        elif self.platform == 'linux':
            btn_map = {'left': '1', 'middle': '2', 'right': '3'}
            btn = btn_map.get(button, '1')
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
btn_map = {'left': '1', 'middle': '2', 'right': '3'}
            btn = btn_map.get(button, '1')
            for _ in range(clicks):
                subprocess.run(['xdotool', 'click', btn], check=False)

    def mouse_drag(self, from_x: int, from_y: int, to_x: int, to_y: int,
                   button: str = "left") -> None:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
btn_map = {'left': '1', 'middle': '2', 'right': '3'}
            btn = btn_map.get(button, '1')
            for _ in range(clicks):
                subprocess.run(['xdotool', 'click', btn], check=False)

    def mouse_drag(self, from_x: int, from_y: int, to_x: int, to_y: int,
                   button: str = "left") -> None:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
button: str = "left") -> None:
        """Drag mouse"""
        if self.platform == 'linux':
            subprocess.run(['xdotool', 'mousemove', str(from_x), str(from_y),
                          'mousedown', '1', 'mousemove', str(to_x), str(to_y),
                          'mouseup', '1'], check=False)
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def mouse_position(self) -> Tuple[int, int]:
        """Get mouse position"""
        if self.platform == 'linux':
            result = subprocess.run(['xdotool', 'getmouselocation'],
                                  capture_output=True, text=True, check=False)
            # Parse "x:123 y:456 screen:0 window:789"
            output = result.stdout.strip()
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def type_text(self, text: str, delay: Optional[float] = None) -> None:
        """Type text"""
        if self.platform == 'macos':
            subprocess.run(['cliclick', 't:', text], check=False)
        elif self.platform == 'linux':
            subprocess.run(['xdotool', 'type', text], check=False)
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if self.platform == 'macos':
            subprocess.run(['cliclick', 't:', text], check=False)
        elif self.platform == 'linux':
            subprocess.run(['xdotool', 'type', text], check=False)

    def key_press(self, keys: List[str]) -> None:
        """Press key combination"""
Confidence
70% confidence
Finding
Although this is not shell injection, it allows arbitrary caller-supplied text to be injected into the active desktop context with no trust boundary, confirmation, or field targeting. In a remote desktop-control skill, this can be abused to enter commands, secrets, or approvals into privileged applications and materially increases the risk of unintended system actions.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if self.platform == 'linux':
            key_str = '+'.join(keys)
            subprocess.run(['xdotool', 'key', key_str], check=False)
        elif self.platform == 'macos':
            # Convert to cliclick format
            key_map = {
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
'tab': 'tab'
            }
            key_str = ','.join([key_map.get(k, k) for k in keys])
            subprocess.run(['cliclick', 'kp:' + key_str], check=False)

    def key_down(self, key: str) -> None:
        """Hold key down"""
Confidence
72% confidence
Finding
This supports arbitrary key combinations assembled from caller-controlled input, enabling shortcuts such as launching terminals, invoking system dialogs, or confirming privileged actions. In context, broad keyboard automation without policy checks is dangerous because it can drive the host beyond simple UI assistance.

Static analysis

No suspicious patterns detected.