Back to skill

Security audit

Desktop Control

Security checks for vulnerabilities and agentic risk

Overview

This desktop automation skill is mostly coherent, but it gives broad live-desktop control with incomplete approval coverage and weak handling of screenshots, clipboard data, and typed secrets.

Install only if you are comfortable giving the skill broad control over your active desktop. Keep failsafe enabled, avoid using it around passwords or confidential documents, do not rely on approval mode as covering every sensitive action, review logs and saved screenshots, and use a virtual environment with pinned dependency versions where possible.

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

T09 · Insecure Skill Coding Practices

Warning
Location
__init__.py:123
Finding
Approval Mode Does Not Protect All Sensitive Operations<![CDATA[ ## Vulnerability Details **File Location**: `__init__.py:123-140`, `__init__.py:198-205`, `__init__.py:210-228`, and `__init__.py:348-380` **Vulnerability Type**: Incomplete authorization enforcement **Risk Level**: Medium ### Vulnerable Code ```python def scroll(self, clicks: int, direction: str = 'vertical', x: Optional[int] = None, y: Optional[int] = None) -> None: if x is not None and y is not None: pyautogui.moveTo(x, y) if direction == 'vertical': pyautogui.scroll(clicks) else: pyautogui.hscroll(clicks) logger.debug(f"Scrolled {direction} {clicks} clicks") def key_down(self, key: str) -> None: """Press and hold a key without releasing.""" pyautogui.keyDown(key) logger.debug(f"Key down: '{key}'") def key_up(self, key: str) -> None: """Release a held key.""" pyautogui.keyUp(key) logger.debug(f"Key up: '{key}'") def screenshot(self, region: Optional[Tuple[int, int, int, int]] = None, filename: Optional[str] = None): img = pyautogui.screenshot(region=region) if filename: img.save(filename) logger.info(f"Screenshot saved to: {filename}") else: logger.debug(f"Screenshot captured (region={region})") return img def copy_to_clipboard(self, text: str) -> None: try: import pyperclip pyperclip.copy(text) logger.info(f"Copied to clipboard: '{text[:50]}...'") except ImportError: logger.error("pyperclip not installed. Run: pip install pyperclip") except Exception as e: logger.error(f"Error copying to clipboard: {e}") def get_from_clipboard(self) -> Optional[str]: try: import pyperclip text = pyperclip.paste() logger.debug(f"Got from clipboard: '{text[:50]}...'") return text except ImportError: logger.error("pyperclip not installed. Run: pip install pyperclip") return None except Exception as e: log ...[truncated 1997 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Apply `_check_approval()` before every state-changing or privacy-sensitive operation, including: - Screen and region capture - Clipboard reads and writes - Scrolling - `key_down()` and `key_up()` - Window enumeration and activation where relevant - Pixel inspection and image matching if screen confidentiality is expected 2. Introduce capability-specific permissions such as `allow_screen_capture`, `allow_clipboard_read`, `allow_clipboard_write`, and `allow_input_control`. 3. Default privacy-sensitive capabilities to denied when approval mode is enabled. 4. Ensure the approval prompt displays the operation and its scope, such as the screenshot region or clipboard access direction. 5. Add automated tests that enumerate every public controller method and verify that sensitive methods cannot execute after approval is declined. 6. Document precisely which methods are protected rather than describing approval mode as applying universally. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
__init__.py:153
Finding
Typed and Clipboard Content Is Exposed Through Application Logs<![CDATA[ ## Vulnerability Details **File Location**: `__init__.py:153-170` and `__init__.py:348-360` **Vulnerability Type**: Plaintext sensitive-data exposure through logging **Risk Level**: Medium ### Vulnerable Code ```python def type_text(self, text: str, interval: float = 0, wpm: Optional[int] = None) -> None: """ Type text with configurable speed. Args: text: Text to type interval: Delay between keystrokes (0 = instant) wpm: Words per minute (overrides interval, typical human: 40-80 WPM) """ if wpm is not None: # Convert WPM to interval (assuming avg 5 chars per word) chars_per_second = (wpm * 5) / 60 interval = 1.0 / chars_per_second if self._check_approval(f"type text: '{text[:50]}...'"): pyautogui.write(text, interval=interval) logger.info( f"Typed text: '{text[:50]}{'...' if len(text) > 50 else ''}' " f"(interval={interval:.3f}s)" ) def copy_to_clipboard(self, text: str) -> None: """ Copy text to clipboard. Args: text: Text to copy """ try: import pyperclip pyperclip.copy(text) logger.info(f"Copied to clipboard: '{text[:50]}...'") except ImportError: logger.error("pyperclip not installed. Run: pip install pyperclip") except Exception as e: logger.error(f"Error copying to clipboard: {e}") ``` ### Technical Analysis The controller records up to the first 50 characters of typed and copied content at INFO level. The project documentation explicitly demonstrates form filling, password entry, email text, and clipboard manipulation. Consequently, these values may include passwords, access tokens, personal information, recovery codes, or confidential business data. INFO logs are commonly enabled in production and may be retained in terminal history, service logs, diagnostic archives, or centralized logging systems. Truncating data to 50 characters is not mea ...[truncated 1267 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove content values from INFO, warning, and error logs. 2. Record only non-sensitive metadata, for example: ```python logger.info("Typed text (%d characters)", len(text)) logger.info("Copied text to clipboard (%d characters)", len(text)) ``` 3. Do not include typed content in approval prompts by default. Use a description such as “Type 24 characters into the active window.” 4. If content-level debugging is necessary, require an explicit development-only option and apply structured redaction for passwords, tokens, email addresses, and other sensitive fields. 5. Ensure secret logging remains disabled by default and add tests asserting that supplied text does not appear in captured log output. 6. Document that clipboard and typing operations may process secrets and establish an appropriate log-retention policy. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
ai_agent.py:357
Finding
Unvalidated Application Value Can Be Executed Through the Windows Run Dialog<![CDATA[ ## Vulnerability Details **File Location**: `ai_agent.py:357-369` **Vulnerability Type**: Command injection through GUI automation **Risk Level**: Medium ### Vulnerable Code ```python def _do_launch_app(self, app: str) -> None: """Launch an application.""" # Get launch command from knowledge base app_info = self.app_knowledge.get(app, {}) launch_cmd = app_info.get("launch_command", app) # Open Run dialog self.dc.hotkey('win', 'r') time.sleep(0.5) # Type and execute command self.dc.type_text(launch_cmd, wpm=100) self.dc.press('enter') logger.info(f"Launched: {app}") ``` The dispatch path accepts a step-provided application value: ```python if step_type == "launch_app": self._do_launch_app(step["app"]) result["success"] = True ``` ### Technical Analysis Known applications are mapped to fixed launch commands, but unknown values fall back to the original `app` string: ```python launch_cmd = app_info.get("launch_command", app) ``` That string is entered verbatim into the Windows Run dialog and executed by pressing Enter. Therefore, the `app` field functions as a command string rather than a constrained application identifier. The normal natural-language planner currently resolves unknown application requests to Notepad, reducing exposure through that specific path. However, `_execute_step()` accepts a caller-supplied dictionary, and the documentation presents individual step execution as a manual API. Future LLM integration could also make generated step content untrusted. Any caller able to supply a `launch_app` step can therefore reach the unsafe fallback. ### Attack Path 1. An integration, plugin, future LLM planner, or other untrusted caller can invoke `_execute_step()` with a crafted step. 2. The caller supplies: ```python { "type": "launch_app", "app": "<attacker-controlled Windows Run command>" } ``` 3. `_do_launch_app()` fails to find the value in `app_knowle ...[truncated 760 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the fallback to the caller-provided value: ```python app_info = self.app_knowledge.get(app) if app_info is None: raise ValueError(f"Unsupported application: {app}") launch_cmd = app_info["launch_command"] ``` 2. Treat `app` as an allowlisted identifier, not as a command. 3. Store executable paths and fixed argument arrays separately, and avoid shell-style command strings. 4. Require explicit approval that displays the exact executable path and arguments immediately before launching. 5. Validate all generated or externally supplied plan steps against a strict schema before execution. 6. Restrict `_execute_step()` from serving as an unguarded public execution interface, or expose a safe wrapper that accepts only supported action identifiers. 7. Run the automation process without administrative privileges and isolate it from sensitive files where possible. 8. Add tests confirming that unknown application names and strings containing command syntax are rejected. ]]>

T08 · Insecure Dependencies

Note
Location
SKILL.md:56
Finding
Installation Instructions Use Unpinned Third-Party Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:56`, `SKILL.md:618`, and `QUICK_REFERENCE.md:250` **Vulnerability Type**: Unpinned dependency installation **Risk Level**: Low ### Vulnerable Code ```bash pip install pyautogui pillow opencv-python pygetwindow ``` The quick-reference documentation additionally recommends: ```bash pip install pyautogui pillow opencv-python pygetwindow pyperclip ``` ### Technical Analysis The installation commands request package names without reviewed version constraints or integrity hashes. Package resolution therefore depends on the mutable state of the configured Python package index at installation time. No typosquatted package name, nonstandard package source, or known malicious dependency was identified in the reviewed files. Nevertheless, installing unconstrained latest versions makes builds non-reproducible and can introduce a compromised, incompatible, or unexpectedly changed future release. The consequence is particularly relevant because these dependencies run inside a desktop-automation process with access to keyboard input, screenshots, window information, and clipboard data. ### Attack Path 1. A user follows the documented installation command. 2. `pip` resolves the newest versions available through the user's configured index and mirrors. 3. A compromised upstream release, compromised index account, unsafe mirror, or future dependency change is selected. 4. Package installation or import executes the dependency's code in the user's environment. 5. Malicious dependency code receives the same process-level access as the desktop automation package. ### Impact Assessment A compromised dependency could execute arbitrary code with the privileges of the installing or running user. Given the purpose of the application, this may expose desktop screenshots, clipboard contents, input events, local files, and accessible account sessions. The audit found no evidence that the currently named dependencies ...[truncated 123 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a reviewed lock file or requirements file with exact versions. 2. Use hashes for every distribution, for example through `pip-compile --generate-hashes` and `pip install --require-hashes`. 3. Keep direct and transitive dependencies under automated vulnerability monitoring. 4. Test dependency upgrades before publishing a new skill release. 5. Recommend installation inside an isolated virtual environment. 6. Specify a trusted Python package index and warn against unreviewed mirrors. 7. Keep the dependency list consistent across `SKILL.md` and `QUICK_REFERENCE.md`, including `pyperclip` where clipboard functionality is documented. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (20)

Missing User Warnings

High
Confidence
95% confidence
Finding
The guide states that the agent takes screenshots and later shows screenshot retention in results, but it does not warn that captures may include passwords, personal data, confidential documents, or other sensitive on-screen material. Because this is a desktop automation skill with broad screen visibility, silent capture and storage materially increases privacy and data-exposure risk.

Missing User Warnings

High
Confidence
97% confidence
Finding
The guide presents disabling the failsafe as a simple configuration option without prominently warning that this removes an important control against runaway or misdirected autonomous input. In a tool that can drive mouse and keyboard across arbitrary desktop applications, removing the failsafe can amplify mistakes into uncontrolled clicks, typing, file changes, or irreversible user actions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared description frames the skill as desktop automation, but the documented capabilities extend into privacy- and control-sensitive areas such as window enumeration, clipboard read/write, and user prompt/approval flows. This mismatch can cause operators or policy systems to under-estimate the skill’s access level, making it easier to deploy a capability that can inspect sensitive context and manipulate the active desktop beyond what the summary suggests.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The guide frames the agent as able to understand and autonomously execute arbitrary natural-language desktop tasks without describing clear scope restrictions, confirmation requirements, or trust boundaries. In a desktop-control skill, this increases the chance that ambiguous or casually phrased user input could trigger impactful real-world actions such as launching apps, typing content, or manipulating UI state.

Vague Triggers

Medium
Confidence
91% confidence
Finding
Example phrases like broad text-entry requests are underspecified and resemble ordinary conversation, making intent detection error-prone. For an autonomous desktop agent, weakly specific triggers can cause unintended execution in the wrong application or context, leading to accidental data entry, message sending, or workflow disruption.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The file and data-handling examples encourage autonomous operations on user content without warning about accidental overwrites, corruption, unintended disclosure, or actions on the wrong files. In a desktop agent context, autonomous file manipulation is especially risky because mistakes directly affect real user data and may be difficult to undo.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The documentation provides screenshot capture and file-saving examples without any privacy, consent, or sensitive-data handling guidance. Because this skill is specifically for desktop control, screenshots may capture credentials, personal data, internal documents, or other sensitive on-screen content, and saving them to disk increases persistence and exposure risk.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The quick reference explicitly shows `DesktopController(failsafe=False)` as a maximum-speed option and labels it as having 'no safety checks' without an adequate warning about the risks. In a desktop automation skill, disabling failsafes can allow unintended clicks, keystrokes, window switching, or destructive actions to continue without an easy abort path, increasing the chance of harmful or uncontrolled system interaction.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill documents comprehensive mouse and keyboard automation, including clicks, drags, hotkeys, and text entry, but does not clearly warn that these actions can modify files, submit forms, trigger system shortcuts, or otherwise change system state destructively. In a desktop-agent setting, simulated input is especially risky because it operates with the user’s ambient privileges and can affect whichever window is focused.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The documentation advertises screenshot capture, image recognition, pixel inspection, and clipboard access without an explicit privacy warning. These features can expose passwords, personal data, tokens, messages, or confidential business information from the screen or clipboard, especially in an agent context where actions may be automated at scale.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
Screenshot capture can collect highly sensitive on-screen information, including emails, credentials, financial data, or private documents, and saving images to disk increases persistence and exposure. Because this occurs without approval or a prominent warning, the skill can silently surveil the user environment.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
Window enumeration and activation allow the skill to inspect application titles and manipulate desktop focus, which goes beyond basic mouse/keyboard/screen control as described. This can reveal sensitive context such as open apps/documents and can be used to redirect subsequent keystrokes or clicks into unintended windows.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The skill description limits scope to mouse, keyboard, and screen automation, but the implementation also reads from and writes to the system clipboard. Clipboard contents often contain passwords, tokens, private messages, or copied documents, so adding this capability materially expands data-access scope beyond the stated purpose and creates a covert exfiltration/privacy risk.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
Clipboard writes can overwrite user data and facilitate staging of sensitive or deceptive content for later paste operations, especially when combined with keyboard automation. Without approval or warning, this can unexpectedly alter user workflow or inject harmful commands, URLs, or text into other applications.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The agent autonomously interprets natural-language tasks and then launches applications, sends keystrokes, and performs mouse actions on the user's live desktop without any explicit consent flow, risk acknowledgment, or constrained permission model. In a desktop-automation skill, this is materially dangerous because ambiguous or unsafe prompts can trigger unintended system interaction, application launches, or input into the wrong window, enabling misuse or destructive actions even if the feature is presented as convenience automation.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The code captures full desktop screenshots before and after each action and stores them in the returned result structure without a clear user-facing privacy notice or consent mechanism. Desktop screenshots can contain highly sensitive information such as emails, documents, passwords, tokens, chats, or regulated data, so collecting them by default increases privacy and data-exposure risk substantially.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The screenshot step writes image files to disk using a default filename without any explicit warning, storage policy, or access protections. Persisting desktop screenshots on disk creates durable artifacts that may expose sensitive on-screen content to other local users, backup systems, malware, or later accidental disclosure.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The demo captures screenshots and writes them to disk automatically, including a full-screen image, without an explicit confirmation immediately before the sensitive action. In a desktop automation skill, screenshots can contain secrets, personal data, or other application content, so persisting them to files increases privacy and data exposure risk if the user did not fully understand what would be captured.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The demo reads the current clipboard, overwrites it with new content, and prints clipboard values to the console after only a generic prompt to continue. Clipboard data often contains passwords, tokens, personal information, or business data, so reading, displaying, and modifying it without a strong privacy warning and explicit scoped consent creates a real confidentiality and integrity risk.

Missing User Warnings

Low
Confidence
78% confidence
Finding
Activating a window changes the user's active context and can cause subsequent automated input to be sent to a different application than expected. On its own this is lower impact, but in a desktop automation skill it increases the chance of unintended or misleading interactions if performed silently.

Static analysis

No suspicious patterns detected.