Back to skill

Security audit

Rustdesk Screenshot

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says, but it can expose RustDesk access credentials and can delete arbitrary contents from a configurable screenshot folder.

Review carefully before installing. Only run this in a controlled Windows environment, with `SCREENSHOT_DIR` set to a dedicated empty folder you are willing to have cleared. Do not use it to capture passwords, temporary RustDesk access codes, private messages, or other secrets, and avoid running it with elevated privileges.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/screenshot.py:18
Finding
Unrestricted Recursive Deletion Through Configurable Screenshot Directory## Vulnerability Details **File Location**: `scripts/screenshot.py`, lines 18 and 48–62 **Vulnerability Type**: Arbitrary directory content deletion through an unvalidated environment-controlled path **Risk Level**: High ```python SCREENSHOT_DIR = os.environ.get("SCREENSHOT_DIR", r"D:\CopyFromScreen") ``` ```python def prepare_screenshot_dir(): """准备截图目录:存在则清空,不存在则创建。""" target = Path(SCREENSHOT_DIR) if target.exists(): if target.is_dir(): for item in target.iterdir(): if item.is_file(): item.unlink() elif item.is_dir(): shutil.rmtree(item) else: target.unlink() target.mkdir(parents=True) else: target.mkdir(parents=True) ``` ### Technical Analysis The `SCREENSHOT_DIR` value is read directly from the process environment and used as the deletion target without validating its resolved location, ownership, type, or relationship to an approved screenshot directory. If the selected path is an existing directory, the script deletes every immediate file and recursively removes every immediate subdirectory. It does not verify that the directory was created by this skill, reject filesystem roots or sensitive locations, require a dedicated marker file, or limit deletion to generated PNG files. The code also performs separate path checks followed by destructive operations, leaving potential filesystem race conditions. Symbolic links, junctions, or other reparse-point behavior may further undermine assumptions about where deletion occurs, depending on the Windows filesystem configuration and Python runtime behavior. ### Attack Path 1. An attacker, wrapper process, compromised launcher, or user-controlled execution environment sets `SCREENSHOT_DIR` to an existing writable directory containing valuable data. 2. The skill is invoked with `python scripts/screenshot.p ...[truncated 1044 chars]
Remediation
## Remediation Suggestions 1. Do not recursively clear an arbitrary environment-supplied directory. Create a unique, dedicated output directory for each execution instead. 2. Resolve the configured path with `Path.resolve()` and require it to be a descendant of a fixed, application-owned base directory. 3. Explicitly reject filesystem roots, drive roots, home directories, known system directories, and paths that equal the approved base directory itself. 4. Reject symbolic links, junctions, and other reparse points before performing destructive operations. 5. Place a private marker file in directories created by the skill and refuse cleanup unless the marker is present and valid. 6. Delete only files matching the skill's expected filename pattern and extension rather than deleting all directory contents. 7. Use restrictive directory permissions and run the script without administrative privileges. 8. Handle path validation and deletion defensively to reduce time-of-check/time-of-use race conditions. 9. Prefer retention limits or collision-resistant filenames over clearing previous output.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:61
Finding
Unpinned Third-Party Dependency Installation## Vulnerability Details **File Location**: `SKILL.md`, line 61 **Vulnerability Type**: Mutable third-party dependency installation without version or integrity verification **Risk Level**: Medium ```text - Pillow (`pip install Pillow`) ``` ### Technical Analysis The installation instruction retrieves Pillow without specifying an audited version, lock file, package hash, or trusted package index. As a result, the installed dependency can change independently of the reviewed skill. This prevents reproducible deployment and leaves installation dependent on the current state of the configured Python package registry. A future compromised upstream release, registry compromise, or maliciously configured package source could introduce unexpected code during installation or subsequent import. The project does not contain evidence that Pillow itself is currently malicious. The risk arises from the mutable and unverified dependency resolution process. ### Attack Path 1. A user follows the documented instruction and executes `pip install Pillow`. 2. `pip` resolves the package from the user's configured package index without a project-defined version or integrity hash. 3. If the selected source or resolved release has been compromised, malicious package content is downloaded and installed. 4. The package's installation behavior or imported runtime code executes with the permissions of the user running the command or the screenshot script. 5. The malicious dependency could then access data and resources available to that account. ### Impact Assessment Successful supply-chain exploitation would execute dependency-controlled code with the privileges of the installing user and, when imported, the user running the skill. Potential scope includes reading or modifying accessible files, capturing sensitive desktop content, accessing process environment data, and executing additional local actions. If dependency installation or skill ...[truncated 175 chars]
Remediation
## Remediation Suggestions 1. Pin Pillow to a specifically reviewed version in a dependency manifest. 2. Generate a lock file containing cryptographic hashes for all resolved distributions. 3. Install with hash verification, such as `pip install --require-hashes -r requirements.txt`. 4. Use an explicitly configured trusted package index or an internally controlled package mirror. 5. Review and update pinned dependencies through a controlled maintenance process that includes vulnerability scanning. 6. Install dependencies in an isolated virtual environment under a non-administrative account. 7. Document the supported Python and Pillow versions to ensure reproducible behavior.
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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (14)

Missing User Warnings

High
Confidence
97% confidence
Finding
The skill description says it may clean the screenshot directory but does not clearly warn that existing contents may be deleted. Deletion of a user-specified or environment-controlled directory can cause data loss, and the absence of prominent warning undermines informed consent and safe operation.

Ssd 3

High
Confidence
98% confidence
Finding
The documentation explicitly instructs that the screenshot can be used to reveal a forgotten temporary RustDesk password, which is sensitive remote-access data. This normalizes exfiltration of credentials through the skill and makes the skill substantially more dangerous than a routine screenshot helper.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill invokes a Python script, relies on environment variables, and performs shell-capable actions, but it declares no explicit tool scope or permissions boundaries. That makes the capability surface implicit rather than governed, increasing the risk of unintended execution context, misuse, or later expansion into unsafe behavior without review.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill performs a full-screen capture but does not prominently warn that all visible content may be collected, including messages, documents, passwords, or remote session details. Because the skill explicitly manipulates the desktop and launches remote-access software, the privacy risk is elevated by context.

Vague Triggers

Medium
Confidence
89% confidence
Finding
A generic trigger example like '运行截图技能' is too vague to reliably signal informed consent for this skill's actual behavior, which includes opening RustDesk, deleting directory contents, and taking a full-screen capture. Ambiguous invocation increases the chance of accidental privacy-impacting execution.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger condition includes broad language such as any instruction involving RustDesk plus screenshots, which can cause the skill to activate when the user did not clearly consent to launching software and capturing the full screen. Overbroad activation is dangerous here because the action affects privacy and can expose sensitive on-screen information.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The note that the skill can be used to view a forgotten RustDesk temporary password turns a screenshot utility into a credential-recovery mechanism for remote access. This materially changes the security profile because the skill can expose authentication secrets unrelated to a benign screenshot workflow.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
The skill minimizes all windows before taking a screenshot, which is a UI-manipulation capability beyond simply launching RustDesk and capturing an image. In context, this can hide what the user was doing, alter desktop state, and suppress visibility into what is being captured or launched, making the behavior more privacy-sensitive and suspicious.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def show_desktop():
    """通过 COM 对象最小化所有窗口,显示桌面。"""
    try:
        subprocess.run(
            [
                "powershell",
                "-NoProfile",
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
exe_path = Path(RUSTDESK_PATH)
    if not exe_path.exists():
        raise FileNotFoundError(f"找不到 RustDesk 可执行文件: {RUSTDESK_PATH}")
    subprocess.Popen(
        [str(exe_path)],
        shell=True,
        stdout=subprocess.DEVNULL,
Confidence
97% confidence
Finding
The script launches an executable path derived from the RUSTDESK_PATH environment variable using subprocess.Popen with shell=True. This creates an avoidable command-execution risk because a manipulated environment value can cause execution of an unintended program, and shell invocation increases the attack surface unnecessarily.

Tainted flow: 'exe_path' from os.environ.get (line 41, credential/environment) → subprocess.Popen (code execution)

Medium
Category
Data Flow
Content
exe_path = Path(RUSTDESK_PATH)
    if not exe_path.exists():
        raise FileNotFoundError(f"找不到 RustDesk 可执行文件: {RUSTDESK_PATH}")
    subprocess.Popen(
        [str(exe_path)],
        shell=True,
        stdout=subprocess.DEVNULL,
Confidence
98% confidence
Finding
The executable path comes from an environment variable and is then executed, creating a tainted path-to-execution flow. In a skill or agent environment where callers or wrappers may influence environment variables, this can be abused to run arbitrary code instead of RustDesk.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script recursively deletes all files and subdirectories under SCREENSHOT_DIR without confirmation, and that directory is environment-configurable. If the path is misconfigured or maliciously set to an important location, the cleanup step can destroy unrelated user data.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The script captures all screens after launching a remote desktop tool, without an explicit consent prompt or warning at runtime. In this context, that can expose sensitive information from multiple monitors and increases privacy risk, especially because the skill is designed to automate capture rather than merely assist the user.

Natural-Language Policy Violations

Low
Confidence
76% confidence
Finding
The skill description specifies trigger phrases only in Chinese and the operational instructions are written exclusively in Chinese. This may constitute a locale/language policy issue if the environment expects language choice or user opt-in rather than a fixed language.

Static analysis

No suspicious patterns detected.