Back to skill

Security audit

macOS Desktop Control Enhanced

Security checks for vulnerabilities and agentic risk

Overview

This skill openly aims to control a Mac desktop, but it exposes sensitive and destructive desktop actions without enough scoping, safeguards, or input validation.

Review before installing. This skill can capture visible screen content, read or overwrite the clipboard, type and click in the active desktop, and terminate processes or apps. Only use it in a controlled environment with explicit user-directed commands, and do not pass untrusted web, file, clipboard, or model-generated values into its desktop-control functions without validation.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/desktop_control.py:70
Finding

AppleScript Injection Through Unsanitized Desktop-Control Parameters

Content
View full analysis

Vulnerability Details

File Location: scripts/desktop_control.py, lines 70–161
Vulnerability Type: AppleScript injection leading to arbitrary command execution
Risk Level: High

The following public functions insert caller-controlled values directly into dynamically generated AppleScript source.

Affected Code

Clipboard text — lines 70–73

python
def set_clipboard(text):
    """Set clipboard to given text."""
    script = f'set the clipboard to "{text}"'
    subprocess.run(["osascript", "-e", script], check=True)

Application bundle identifier — lines 103–105

python
def focus_app(bundle_id):
    """Bring the given app to foreground."""
    subprocess.run(["osascript", "-e", f'tell application "{bundle_id}" to activate'], check=True)

Mouse coordinates — lines 111–117

python
def move_mouse(x, y):
    """Move cursor to screen coordinates (x, y)."""
    script = f'''
    tell application "System Events"
        set cursor to POSIX point {x}, {y}
    end tell
    '''
    subprocess.run(["osascript", "-e", script], check=True)

Click coordinates — lines 120–133

python
def click(x, y, button="left"):
    """Perform a mouse click at (x, y)."""
    down = f'''
    tell application "System Events"
        mouse down at POSIX point {x}, {y}
    end tell
    '''
    up = f'''
    tell application "System Events"
        mouse up at POSIX point {x}, {y}
    end tell
    '''
    subprocess.run(["osascript", "-e", down], check=True)
    subprocess.run(["osascript", "-e", up], check=True)

Keyboard text — lines 149–156

python
def type_text(text):
    """Type the given string."""
    script = f'''
    tell application "System Events"
        keystrokes "{text}"
    end tell
    '''
    subprocess.run(["osascript", "-e", script], check=True)

Key code — lines 158–161

python
def p
...[truncated 3051 chars]
Remediation
View remediation

Remediation Suggestions

  1. Never interpolate caller-controlled data into AppleScript source. Use a fixed script and pass values through osascript command-line arguments:

    python
    script = '''
    on run argv
        set the clipboard to item 1 of argv
    end run
    '''
    subprocess.run(["osascript", "-e", script, str(text)], check=True)
    
  2. Use the same argument-passing pattern for keyboard text and bundle identifiers. Retrieve values from argv inside a fixed AppleScript program rather than constructing source with Python f-strings.

  3. Validate bundle identifiers. Reject values that do not match a strict format such as:

    python
    r"^[A-Za-z0-9][A-Za-z0-9.-]*$"
    
  4. Enforce numeric types for coordinates and key codes. Reject booleans, strings, floating-point values, negative values where unsupported, and values outside documented screen or key-code ranges:

    python
    if not isinstance(x, int) or isinstance(x, bool):
        raise TypeError("x must be an integer")
    
  5. Prefer native Python APIs or trusted automation libraries that represent arguments as typed values rather than executable AppleScript source.

  6. Apply least privilege. Grant the hosting process only the macOS Automation, Screen Recording, and Accessibility permissions required for the intended workflow.

  7. Add adversarial tests covering quotation marks, backslashes, multiline strings, control characters, AppleScript statement separators, extremely large integers, and strings supplied where integers are expected.

  8. Document trust boundaries. Explicitly state that values derived from web content, files, clipboard data, model output, or remote requests must not reach desktop-control functions without validation.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (34)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description promises a fully featured macOS desktop control skill, but the provided code does not implement any of those capabilities. It is a minimal example script whose only behavior is printing a placeholder message. This is a material mismatch in primary purpose and functionality: the description represents a powerful desktop automation tool, while the actual code chunk is effectively a stub with no relevant implementation.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

Screenshot capture can collect highly sensitive on-screen information, including credentials, personal data, documents, and security prompts, and this function saves that data to disk without any warning. The skill context makes this more dangerous because the tool is explicitly intended for remote desktop automation, so covert capture is a plausible abuse path.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

Force-killing processes without any warning, confirmation, or policy gating is dangerous in a desktop automation skill because it can abruptly terminate user work, security software, or critical applications. The skill context increases danger: this capability is system-wide and could be triggered remotely by an agent workflow rather than a local user knowingly invoking it.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

Application termination is a destructive action, and this implementation performs it without any user disclosure or confirmation. In a general-purpose desktop-control skill, silent app termination can cause data loss and can be abused to disable defenses or interrupt user activity.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill advertises powerful desktop-control capabilities that would likely require shell or equivalent execution, but it declares no explicit tool scope or permission boundaries. This creates an authorization gap where an agent or user may invoke sensitive functionality without clear consent, review, or least-privilege restrictions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill explicitly includes screenshot capture, clipboard access, and process or application termination, all of which can expose sensitive data or disrupt a user's work, yet it provides no warning, consent model, or safety guidance. In context, desktop automation makes this more dangerous because these actions affect the live user environment and may access secrets, personal content, or critical applications.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This markdown file describes a capability that captures the user's screen and writes an image file, but it does not disclose the privacy implications of recording on-screen data or storing it at a filesystem path. Under the markdown-specific warning criterion, user-impacting data capture should be accompanied by a clear warning.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Both kill_process(pid) and terminate_app(bundle_id) are described as terminating software, including force-closing applications, but the documentation provides no warning that unsaved work may be lost. For markdown skill documentation, destructive or system-integrity-affecting behaviors should be clearly disclosed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
79% confidence
Finding

The documented mouse movement, clicking, dragging, text typing, and keypress APIs can directly manipulate the active desktop session and potentially alter data or trigger actions, but the file contains no cautionary disclosure. In markdown documentation, such automation capabilities should include user warnings about focus, active window state, and unintended side effects.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/desktop_control.py (reported line 28)May include surrounding context.

python
cmd.extend(["-r", region])
    target = file_path or "/tmp/screenshot.png"
    cmd.append(target)
    subprocess.run(cmd, check=True)
    return target

# ---------------------------------------------------------------------------

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/desktop_control.py (reported line 52)May include surrounding context.

python
"name": frontAppName
    }}
    '''
    result = subprocess.run(["osascript", "-e", script], capture_output=True, text=True, check=True)
    return json.loads(result.stdout)

def kill_process(pid):

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
91% confidence
Finding

This function force-kills an arbitrary PID with SIGKILL and has no validation, scoping, or user confirmation. In a desktop-control skill, that creates a destructive system-wide capability that can terminate security tools, user applications, or critical processes, causing denial of service or data loss.

Content

Scanner excerpt · scripts/desktop_control.py (reported line 57)May include surrounding context.

python
def kill_process(pid):
    """Kill a process by PID."""
    subprocess.run(["kill", "-9", str(pid)], check=True)

def launch_app(bundle_id):
    """Launch an app by bundle identifier."""

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/desktop_control.py (reported line 61)May include surrounding context.

python
def launch_app(bundle_id):
    """Launch an app by bundle identifier."""
    subprocess.run(["open", f"--b {bundle_id}"], check=True)

def terminate_app(bundle_id):
    """Force‑close an app by bundle identifier."""

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The function claims to perform application control via AppleScript but actually feeds shell-style pkill -f text to osascript, which is inconsistent and unsafe. This mismatch can mislead reviewers and users about what is executed, obscuring destructive behavior and compounding the injection risk from unsanitized bundle_id.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
99% confidence
Finding

The AppleScript content is built with unsanitized bundle_id and passed to osascript -e, enabling AppleScript code injection if the input contains quotes or script syntax. That can lead to arbitrary AppleScript execution and, depending on automation permissions, broad system control or indirect command execution.

Content

Scanner excerpt · scripts/desktop_control.py (reported line 68)May include surrounding context.

python
script = f'''
    pkill -f "{bundle_id}"
    '''
    subprocess.run(["osascript", "-e", script], check=True)

# ---------------------------------------------------------------------------
# Clipboard

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Clipboard reads are privacy-sensitive because users often copy passwords, tokens, personal messages, and financial data. In a system-wide automation skill, reading the clipboard without disclosure or contextual consent creates a realistic exfiltration risk even if the implementation is otherwise straightforward.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/desktop_control.py (reported line 75)May include surrounding context.

python
# ---------------------------------------------------------------------------
def get_clipboard():
    """Get current clipboard text."""
    result = subprocess.run(["osascript", "-e", 'the clipboard as string'], capture_output=True, text=True, check=True)
    return result.stdout.strip()

def set_clipboard(text):

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Overwriting the clipboard without warning can destroy user data in transit and facilitate phishing or command substitution attacks by replacing copied content. In a desktop-control tool, silent clipboard modification is especially risky because users may paste the altered content into privileged contexts.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
98% confidence
Finding

The code embeds arbitrary text directly into AppleScript string syntax without escaping, so crafted input containing quotes can break out of the string and inject additional AppleScript statements. This enables arbitrary desktop automation actions under the skill's permissions, making clipboard write a code-injection vector rather than just a benign setter.

Content

Scanner excerpt · scripts/desktop_control.py (reported line 81)May include surrounding context.

python
def set_clipboard(text):
    """Set clipboard to given text."""
    script = f'set the clipboard to "{text}"'
    subprocess.run(["osascript", "-e", script], check=True)

# ---------------------------------------------------------------------------
# System Information

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/desktop_control.py (reported line 89)May include surrounding context.

python
def get_system_info():
    """Return basic macOS system info (OS version, battery)."""
    # OS version
    os_ver = subprocess.run(["sw_vers", "-productVersion"], capture_output=True, text=True, check=True).stdout.strip()
    # Battery (using pmset)
    batt = subprocess.run(["pmset", "-g", "batt"], capture_output=True, text=True, check=True).stdout
    batt_percent = next((m.group(0) for m in [re.search(r'(\d+)%', line) for line in batt.splitlines()] if m), "unknown")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/desktop_control.py (reported line 91)May include surrounding context.

python
# OS version
    os_ver = subprocess.run(["sw_vers", "-productVersion"], capture_output=True, text=True, check=True).stdout.strip()
    # Battery (using pmset)
    batt = subprocess.run(["pmset", "-g", "batt"], capture_output=True, text=True, check=True).stdout
    batt_percent = next((m.group(0) for m in [re.search(r'(\d+)%', line) for line in batt.splitlines()] if m), "unknown")
    return {"os_version": os_ver, "battery": batt_percent}

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
98% confidence
Finding

The function interpolates bundle_id into an AppleScript command string without escaping, allowing AppleScript injection via crafted input. In this skill's context, successful injection can grant an attacker the ability to drive applications, access UI elements, or perform additional system actions using already-granted automation permissions.

Content

Scanner excerpt · scripts/desktop_control.py (reported line 100)May include surrounding context.

python
# ---------------------------------------------------------------------------
def focus_app(bundle_id):
    """Bring the given app to foreground."""
    subprocess.run(["osascript", "-e", f'tell application "{bundle_id}" to activate'], check=True)

def terminate_app(bundle_id):
    """Force‑close the given app."""

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This duplicate terminate_app repeats the same deceptive implementation pattern: documentation implies controlled app termination, but the body contains shell-style process-kill text sent to osascript. Such semantic mismatch hides the true destructive capability and makes security review and safe use harder.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
99% confidence
Finding

Like the earlier terminate_app variant, this call passes dynamically generated AppleScript containing unescaped bundle_id to osascript. That creates a straightforward code-injection path with potentially system-wide automation impact.

Content

Scanner excerpt · scripts/desktop_control.py (reported line 107)May include surrounding context.

python
script = f'''
    pkill -f "{bundle_id}"
    '''
    subprocess.run(["osascript", "-e", script], check=True)

# ---------------------------------------------------------------------------
# Mouse Control

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
78% confidence
Finding

The coordinates are interpolated into AppleScript source without type enforcement, so non-numeric crafted values could alter the script structure and potentially inject AppleScript. Even if typical callers pass integers, leaving this unvalidated in a system-control skill increases risk because the primitive can manipulate global input state.

Content

Scanner excerpt · scripts/desktop_control.py (reported line 119)May include surrounding context.

python
set cursor to POSIX point {x}, {y}
    end tell
    '''
    subprocess.run(["osascript", "-e", script], check=True)

def click(x, y, button="left"):
    """Perform a mouse click at (x, y)."""

Static analysis

No suspicious patterns detected.