Back to skill

Security audit

Linux Desktop Control

Security checks for vulnerabilities and agentic risk

Overview

This Linux desktop automation skill does what it says, but its helper script exposes command-injection paths that can turn normal arguments into arbitrary shell commands.

Review this before installing. The desktop-control behavior is disclosed, but the current script should not be exposed to untrusted prompts, wrappers, filenames, window IDs, typed text, or key values until shell=True is removed and arguments are validated. Use only in a non-sensitive desktop session, avoid password or financial windows, and do not run privileged commands through simulated typing.

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/linux-desktop.py:14
Finding
OS Command Injection Through User-Controlled Command-Line Arguments## Vulnerability Details **File Location**: `scripts/linux-desktop.py:14-21, 25-30, 38-46, 103-115, 168, 178-179, 247, 261` **Vulnerability Type**: OS command injection caused by unsafe shell invocation **Risk Level**: High ### Vulnerable Code ```python def run_command(cmd): """运行 shell 命令""" try: result = subprocess.run( cmd, shell=True, capture_output=True, text=True, timeout=30 ) return result.returncode == 0, result.stdout.strip(), result.stderr.strip() except subprocess.TimeoutExpired: return False, "", "Command timed out" except Exception as e: return False, "", str(e) def take_screenshot(output_path=None): """截图""" if not output_path: timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") output_path = f"/tmp/screenshot_{timestamp}.png" success, stdout, stderr = run_command(f"scrot '{output_path}'") def take_window_screenshot(window_id=None, output_path=None): """截图指定窗口""" if not output_path: timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") output_path = f"/tmp/window_{timestamp}.png" if window_id: success, stdout, stderr = run_command( f"xwd -id {window_id} | convert xwd:- '{output_path}'" ) else: success, stdout, stderr = run_command( f"xwd -root | convert xwd:- '{output_path}'" ) def type_text(text): """输入文本""" success, stdout, stderr = run_command(f"xdotool type '{text}'") def key_press(key): """按键""" success, stdout, stderr = run_command(f"xdotool key {key}") ``` The affected values are populated directly from command-line arguments: ```python output = sys.argv[2] if len(sys.argv) > 2 else None window_id = sys.argv[2] if len(sys.argv) > 2 else None output = sys.argv[3] if len(sys.argv) > 3 else None text = sys.argv[2] key = sys.argv[2] ``` ### Technical Analysis The shared `run_command` fu ...[truncated 2810 chars]
Remediation
## Remediation Suggestions 1. Remove `shell=True` and execute every utility with an argument list: ```python def run_command(args): result = subprocess.run( args, shell=False, capture_output=True, text=True, timeout=30, check=False, ) return result.returncode == 0, result.stdout.strip(), result.stderr.strip() ``` 2. Convert straightforward calls to argument arrays: ```python run_command(["scrot", output_path]) run_command(["xdotool", "type", "--", text]) run_command(["xdotool", "key", key]) run_command(["xdotool", "mousemove", str(x), str(y)]) run_command(["xdotool", "click", str(button)]) ``` 3. Replace the `xwd | convert` shell pipeline with two processes connected explicitly: ```python xwd_args = ["xwd", "-id", window_id] if window_id else ["xwd", "-root"] xwd = subprocess.Popen(xwd_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) convert = subprocess.run( ["convert", "xwd:-", output_path], stdin=xwd.stdout, capture_output=True, timeout=30, check=False, ) if xwd.stdout: xwd.stdout.close() xwd.wait(timeout=30) ``` 4. Validate arguments independently of shell removal: - Restrict window IDs to the formats accepted by `xwd`, such as a decimal integer or a strictly validated hexadecimal X11 ID. - Allow only supported key-specification syntax. - Restrict mouse buttons to the documented set unless broader support is required. - Validate output paths according to the intended file-access policy. - Reject NUL bytes and malformed values. 5. Add regression tests using single quotes, semicolons, newlines, backticks, `$()` substitutions, redirections, and pipeline characters. Verify that each value is passed literally and cannot create additional processes. 6. Apply least privilege: run desktop automation only as the intended graphical user, never as root, and avoid exposing this command interface directly to untrusted input.
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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (12)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
def run_command(cmd):
    """运行 shell 命令"""
    try:
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
        return result.returncode == 0, result.stdout.strip(), result.stderr.strip()
    except subprocess.TimeoutExpired:
        return False, "", "Command timed out"
Confidence
99% confidence
Finding
The tool exposes powerful desktop actions and forwards user-influenced parameters into shell commands, creating a parameter-abuse path to arbitrary command execution. In this skill context, the danger is amplified because the tool already has access to screenshots, keyboard input, mouse control, and window enumeration, so compromise can quickly lead to surveillance and account takeover.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill clearly relies on shell command execution (`python3`, `sudo apt-get`, `sleep`) yet the manifest declares no explicit tool scope or permission boundary. In an agent environment, this increases the chance the skill is invoked with broader execution authority than intended, making desktop control and screenshot functionality riskier and less auditable.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The manifest description is very broad (`any Linux desktop interaction needs`), which can cause an agent to select this skill for many loosely related tasks. Because the skill can capture screens and inject mouse/keyboard input, over-broad routing materially increases the risk of unintended invocation in sensitive contexts.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The usage guidance introduces screenshot capture and input simulation early, but does not place a prominent warning adjacent to those instructions about privacy exposure, credential capture, accidental clicks, or typing into the wrong focused window. For a desktop-control skill, this omission makes misuse more likely because users may follow quick-start examples before reaching later security notes.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
Install required tools:

```bash
sudo apt-get install scrot xdotool xclip x11-utils x11-apps
```

## Quick Start
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
Install required tools:

```bash
sudo apt-get install scrot xdotool xclip x11-utils x11-apps
```

## Quick Start
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
python3 scripts/linux-desktop.py type "ls -la"

python3 scripts/linux-desktop.py type "sudo apt update"
```

### `key <keyspec>`
Confidence
84% confidence
Finding
The documentation includes an example that automates typing `sudo apt update`, which can lead users or agents toward injecting privileged commands into a terminal via simulated keyboard input. In desktop automation, typed commands may land in the wrong window or be executed without sufficient review, creating a realistic path to unintended privileged operations.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## Security Notes

- This skill can control your desktop - use with caution
- Don't automate sensitive actions without verification
- Always review automation scripts before running
Confidence
75% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The natural-language description and all CLI help and status output are presented in Chinese, with no indication that the user can opt into another language. This creates a language policy concern because the skill imposes a specific locale rather than offering a choice or documenting why the restriction is necessary.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def run_command(cmd):
    """运行 shell 命令"""
    try:
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
        return result.returncode == 0, result.stdout.strip(), result.stderr.strip()
    except subprocess.TimeoutExpired:
        return False, "", "Command timed out"
Confidence
98% confidence
Finding
The helper executes shell commands with shell=True while many command strings are built from untrusted CLI inputs such as output_path, window_id, text, and key. This enables command injection, allowing an attacker to break out of quoting or inject shell metacharacters and execute arbitrary commands under the tool's privileges.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
This function captures the full screen and writes it to disk without any user-facing warning, confirmation, or sensitivity notice. In a desktop-control skill, screenshots can collect passwords, personal messages, tokens, and other visible secrets, so silent capture increases privacy and data-handling risk.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
Window-specific capture records the contents of a chosen window without any warning that the target may display sensitive information. Because this skill is explicitly designed for desktop interaction, targeted window capture can be used to exfiltrate focused application data more precisely than full-screen capture.

Static analysis

No suspicious patterns detected.