Back to skill

Security audit

Windows 桌面控制

Security checks for vulnerabilities and agentic risk

Overview

This Windows desktop-control skill is mostly purpose-aligned, but it gives broad desktop authority and contains concrete safety gaps that could let a caller terminate unintended processes or execute PowerShell through clipboard input.

Review carefully before installing. Use only in a trusted, local Windows environment, avoid running it as administrator, and do not let untrusted prompts or content invoke clipboard, keyboard, mouse, screenshot, or process-kill actions. The publisher should fix the clipboard command injection, enforce the process allowlist for PIDs, add explicit confirmations for high-impact actions, and pin dependencies before broad use.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/desktop_ctrl.py:184
Finding
Numeric PID Input Bypasses the Process Termination Allowlist<![CDATA[ ## Vulnerability Details **File Location**: `scripts/desktop_ctrl.py:184-196` **Vulnerability Type**: Process termination authorization bypass **Risk Level**: High ### Vulnerable Code ```python protected_pids = [0, 4] if name_or_pid.isdigit(): if int(name_or_pid) in protected_pids: return {"success": False, "error": "Termination of system processes is prohibited"} ps = f'Stop-Process -Id {name_or_pid} -Force -ErrorAction Stop' else: name_lower = name_or_pid.lower().replace('.exe', '') if name_lower not in ALLOWED_PROCESSES: return { "success": False, "error": f"Only allowlisted processes may be terminated: {', '.join(ALLOWED_PROCESSES)}" } ps = f'Stop-Process -Name "{name_or_pid}" -Force -ErrorAction Stop' subprocess.run( ["powershell", "-ExecutionPolicy", "Bypass", "-NoProfile", "-Command", ps], check=True, timeout=10 ) ``` The messages above are translated into English for reporting; the control flow and executable statements correspond to lines 184-196. ### Technical Analysis The documented process-name allowlist is enforced only when the argument is not numeric. When a PID is supplied, the implementation checks only whether it is PID 0 or PID 4. It does not resolve the PID to its executable and verify that executable against `ALLOWED_PROCESSES`. Consequently, the caller can use the `processes` command to discover PIDs and then forcibly terminate any accessible process other than the two explicitly protected PIDs. PowerShell executes with the current Skill process token; this does not itself elevate privileges, but it exceeds the documented and intended process-control boundary. ### Attack Path 1. Invoke `python scripts/desktop_ctrl.py processes` to enumerate running processes and PIDs. 2. Select the PID of an application, service, security product, or other process outside the name allowlist. 3. Invoke `python scripts/desktop_ctrl.py kill <PID>`. 4. The numer ...[truncated 643 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not treat numeric PIDs as independently authorized targets. - Resolve the PID to its executable name and normalized executable path before termination. - Apply the same allowlist to both process names and PIDs. - Explicitly deny critical Windows processes, services, security products, and processes owned by other users. - Prefer exact executable-path allowlisting rather than process-name-only allowlisting. - Require explicit user confirmation containing the resolved process name, PID, owner, and path before termination. - Avoid `-Force` unless it is necessary for the declared operation. - Run the Skill without administrative privileges and record process-termination attempts in an audit log. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/desktop_ctrl.py:231
Finding
PowerShell Command Injection Through Clipboard Text<![CDATA[ ## Vulnerability Details **File Location**: `scripts/desktop_ctrl.py:231-233` **Vulnerability Type**: OS command injection **Risk Level**: Critical ### Vulnerable Code ```python escaped_text = text.replace('"', '\\"').replace('`', '``') ps = f'Set-Clipboard -Value "{escaped_text}"' subprocess.run( ["powershell", "-ExecutionPolicy", "Bypass", "-NoProfile", "-Command", ps], check=True, timeout=10 ) ``` ### Technical Analysis The implementation inserts caller-controlled clipboard text into a PowerShell command string. It attempts to escape a double quote by prefixing it with a backslash. PowerShell does not use backslash as the escape character for double quotes; therefore, an injected quote can terminate the intended string literal. After closing the string, an attacker can append a PowerShell statement using a command separator and suppress the remaining generated syntax with a comment. Doubling backticks does not make arbitrary command-string interpolation safe. Although `subprocess.run` uses an argument array rather than a shell, this does not mitigate the issue because PowerShell itself receives the attacker-influenced value through its `-Command` parameter and parses it as executable source code. ### Attack Path 1. Invoke the clipboard-set operation with text containing a double quote, a semicolon, a PowerShell command, and a comment marker. 2. For example, a value shaped like `"; Start-Process calc; #` becomes part of the generated PowerShell source. 3. The backslash inserted before the quote is interpreted as a literal character rather than a PowerShell escape. 4. The quote closes the intended `Set-Clipboard` string. 5. PowerShell parses and executes the appended statement with the privileges of the Skill process. The calculator command is only a harmless demonstration. The same primitive could invoke other local commands, scripts, or PowerShell functionality available to the current user. ### Impact Assessment Successful ...[truncated 397 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not construct PowerShell source code by interpolating clipboard content. - Prefer a native Windows clipboard API so the value is handled strictly as data. - If PowerShell must be used, pass the content through standard input or another non-code channel and use a fixed PowerShell script. - Alternatively, encode the text as data in Python and decode it inside a fixed script without evaluating the decoded value. - Do not rely on manual replacement of quotes, backticks, semicolons, newlines, or other metacharacters. - Remove `-ExecutionPolicy Bypass` because it is unnecessary for this operation and weakens defense in depth. - Add regression tests containing quotes, backticks, semicolons, newlines, comment markers, interpolation expressions, and Unicode control characters. - Continue enforcing the existing length limit, but do not treat length validation as an injection defense. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:35
Finding
Unpinned Python Dependencies Create a Supply-Chain Risk<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:8-9, 35` **Vulnerability Type**: Unpinned third-party dependencies **Risk Level**: Medium ### Vulnerable Code ```yaml pip: ["pyautogui", "mss", "pillow"] ``` ```bash pip install pyautogui mss pillow ``` ### Technical Analysis The Skill declares and instructs installation of third-party Python packages without exact versions or integrity hashes. Installation therefore resolves whichever compatible releases are available from the configured package index at installation time. This makes deployment non-reproducible and allows newly published, compromised, or otherwise unsafe package versions to enter the Skill environment without a corresponding review of this project. Python packages can execute code during installation and are imported directly by `desktop_ctrl.py`, so a compromised dependency can execute within the Skill process. The reviewed files do not specify an untrusted package index, a typosquatted name, or a known-malicious package. The finding concerns the absence of version and integrity controls rather than proof that the named packages are currently malicious. ### Attack Path 1. A dependency account, release pipeline, distribution artifact, or configured package index is compromised. 2. A malicious or vulnerable package release becomes the version selected by an unpinned installation. 3. A user follows `pip install pyautogui mss pillow`, or the Skill manager installs the metadata dependencies. 4. Malicious package code executes during installation or when `desktop_ctrl.py` imports the dependency. 5. The code receives the same filesystem, desktop, clipboard, process, and network access as the Skill process. ### Impact Assessment A compromised dependency could execute arbitrary Python code with the privileges of the user installing or running the Skill. Because the Skill is designed for desktop capture and input automation, such a compromise could potentially access screen con ...[truncated 162 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin every direct dependency to a reviewed exact version. - Maintain a lock file that also pins transitive dependencies. - Require package hashes, such as through `pip install --require-hashes`. - Install only from an explicitly configured and trusted package index. - Review dependency licenses, maintainers, release history, and known vulnerability advisories. - Use automated dependency scanning while requiring manual review before version updates. - Install dependencies inside an isolated virtual environment under a non-administrative account. - Document a repeatable process for verifying and updating pinned versions. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/desktop_ctrl.py:57
Finding
Screenshot Data Is Unnecessarily Encoded and Included in Command Output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/desktop_ctrl.py:57-65` **Vulnerability Type**: Sensitive data exposure through command output **Risk Level**: Low ### Vulnerable Code ```python with open(filepath, "rb") as f: b64 = base64.b64encode(f.read()).decode() return { "success": True, "path": filepath, "size": img.size, "base64": b64[:100] + "..." } ``` ### Technical Analysis A screenshot can contain sensitive information such as messages, credentials, private documents, account data, or internal application content. After saving the screenshot to disk, the implementation reads the entire file, Base64-encodes it, and includes a truncated prefix in JSON output. Base64 is reversible encoding rather than encryption. Output may be captured by terminal history, agent transcripts, orchestration logs, telemetry, or other consumers that do not need image data. The returned value is limited to the first 100 Base64 characters, which materially restricts the exposed image content, but the operation is still unnecessary for the declared path-based screenshot workflow and creates avoidable handling of sensitive screen data. No network request, external destination, covert transport, or complete screenshot exfiltration mechanism was found in the reviewed project. This finding is therefore limited to local output and logging exposure. ### Attack Path 1. A caller invokes the `screenshot` command while sensitive content is displayed. 2. The Skill captures and saves the screen. 3. The complete screenshot file is read into memory and Base64-encoded. 4. The first 100 encoded characters are included in standard output. 5. A terminal logger, agent transcript, CI log, or orchestration system retains the response. 6. A party with access to those records can decode the retained prefix and inspect any recoverable image metadata or partial compressed content. ### Impact Assessment The direct exposure is limited because only a short pre ...[truncated 320 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the Base64 field from the default response. - Return only the saved path, dimensions, timestamp, and success status. - If image output is explicitly required, make it an opt-in operation with clear user confirmation. - Avoid writing screenshot-derived bytes to standard output or general-purpose logs. - Apply restrictive filesystem permissions to the screenshot directory and define a retention policy. - Avoid reading and encoding the entire image when only file metadata is needed. - Add redaction or capture-region controls for workflows that do not require a full-screen image. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (16)

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill exposes powerful shell-backed desktop control capabilities, including screenshots, input simulation, process management, and clipboard access, but does not declare any explicit tool scope or permission boundaries. In an agent environment, missing scope declarations increases the chance that the skill can be invoked with broader-than-expected authority, making unauthorized system interaction or privacy-invasive actions easier.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The manifest description is written to activate on Chinese-language user requests and does not indicate any language choice or opt-in. This can violate language/locale policy when a skill implicitly requires a specific language without documenting that constraint or offering alternatives.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill captures screenshots and writes them to disk without any built-in disclosure, confirmation, or privacy guardrails. In a desktop-control context this is especially sensitive because screenshots can expose credentials, financial data, private chats, and other on-screen secrets, and the on-disk copy creates lasting forensic exposure.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
try:
            # 使用简化的命令 - 只获取前10个进程
            ps = "(Get-Process | Select-Object -First 10 | ConvertTo-Json -Compress)"
            result = subprocess.run(
                ["powershell", "-ExecutionPolicy", "Bypass", "-NoProfile", "-Command", ps],
                capture_output=True, text=True, timeout=10
            )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
Automated typing, key presses, and hotkeys can drive arbitrary actions in whatever application currently has focus, including sending messages, changing settings, approving prompts, or exfiltrating data. Without user-facing safeguards, this creates a powerful confused-deputy risk in a desktop-control skill.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
Select-Object -First {top} Id, ProcessName, CPU, WorkingSet64 | 
            ConvertTo-Json
            '''
            result = subprocess.run(
                ["powershell", "-ExecutionPolicy", "Bypass", "-NoProfile", "-Command", ps],
                capture_output=True, text=True, timeout=30
            )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
Process termination is a destructive operation, and this code performs it without explicit confirmation or contextual warning. Even with a process-name allowlist, terminating browsers, editors, or runtimes can cause data loss, interrupt work, or shut down security-relevant software inappropriately.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
return {"success": False, "error": f"只允许结束白名单进程: {', '.join(ALLOWED_PROCESSES)}"}
                ps = f'Stop-Process -Name "{name_or_pid}" -Force -ErrorAction Stop'
            
            subprocess.run(["powershell", "-ExecutionPolicy", "Bypass", "-NoProfile", "-Command", ps], check=True, timeout=10)
            return {"success": True}
        except subprocess.CalledProcessError as e:
            return {"success": False, "error": f"结束进程失败: {e}"}
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The skill metadata describes screenshot, window, input, process, and system-info features, but the implementation can also read and modify clipboard contents. Undisclosed clipboard access is dangerous because clipboards often hold passwords, tokens, personal messages, and other sensitive transient data that users do not expect this skill to access.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
Clipboard reads occur without any user-facing warning or consent flow. Because clipboard contents frequently contain secrets and are not always visible on screen, silent access creates a significant privacy and credential-exposure risk in this skill context.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
return {"success": True, "text": "(无文本)"}
        except:
            ps = 'Get-Clipboard'
            result = subprocess.run(
                ["powershell", "-Command", ps],
                capture_output=True, text=True
            )
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
return {"success": True, "text": "(无文本)"}
        except:
            ps = 'Get-Clipboard'
            result = subprocess.run(
                ["powershell", "-Command", ps],
                capture_output=True, text=True
            )
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
# 转义特殊字符防止注入
            escaped_text = text.replace('"', '\\"').replace('`', '``')
            ps = f'Set-Clipboard -Value "{escaped_text}"'
            subprocess.run(["powershell", "-ExecutionPolicy", "Bypass", "-NoProfile", "-Command", ps], check=True, timeout=10)
            return {"success": True}
        except Exception as e:
            return {"success": False, "error": str(e)}
Confidence
90% confidence
Finding
clipboard_set builds a PowerShell command by embedding user-controlled text inside double quotes, but only escapes double quotes and backticks. PowerShell still performs variable and subexpression expansion inside double-quoted strings, so input like $(...) or $env:... can alter command behavior or trigger unintended command execution.

Missing User Warnings

Low
Confidence
83% confidence
Finding
The skill advertises clipboard write support without warning that it can overwrite user clipboard contents, which may disrupt workflows or replace sensitive copied data. In a desktop-control skill, clipboard mutation is more sensitive because it directly alters user state and can be used to stage unintended pastes into other applications.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The module description and many user-facing strings are written in Chinese, which imposes a language choice on users without any opt-in or explanation that the skill is intended only for a Chinese-speaking context. This is a natural-language locale policy concern because the file does not offer alternatives or document the restriction.

Intent-Code Divergence

Low
Confidence
88% confidence
Finding
The execute_command method is documented as disabled and always returns an error, indicating command execution is not a real capability. However, the CLI help text still presents 'exec <cmd> - 执行命令' as an available command, which contradicts the documented intent and misrepresents the skill's behavior.

Static analysis

No suspicious patterns detected.