Back to skill

Security audit

Virtual Desktop Browser

Security checks for vulnerabilities and agentic risk

Overview

This is a real browser-automation skill, but it is framed for bot-resistant websites and runs powerful click, type, and screenshot automation with weak safety boundaries.

Install only in an isolated, disposable environment with a dedicated browser profile and non-privileged account. Do not use it on accounts, pages, or services where automated clicks, typing, screenshots, or anti-bot circumvention would violate rules or expose private data. Pin the source and dependencies before use, and avoid running Chromium with --no-sandbox unless the surrounding container is hardened.

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

T09 · Insecure Skill Coding Practices

Error
Location
skill.py:76
Finding
Chromium Runs with Its Security Sandbox Disabled## Vulnerability Details **File Location**: `skill.py:76-82` **Vulnerability Type**: Browser isolation disabled **Risk Level**: High ```python chrome_cmd = [ "chromium-browser", "--no-sandbox", "--disable-dev-shm-usage", "--disable-gpu", f"--window-size={FIXED_WIDTH},{FIXED_HEIGHT}", ] chrome_cmd.append(url or "about:blank") ``` ### Technical Analysis The `--no-sandbox` argument disables Chromium's process sandbox, which is a principal defense against malicious web content and renderer vulnerabilities. Visiting untrusted or bot-resistant websites is central to the Skill's declared functionality, so disabling this isolation boundary materially increases exposure. The argument is applied unconditionally. It is therefore used even when Chromium runs as an unprivileged account on a system where the normal Chromium sandbox could operate. This exceeds the minimum privilege configuration necessary in those environments. The Skill does not itself contain a browser exploit. Successful host compromise would require a vulnerability in Chromium or one of its components, but disabling the sandbox substantially increases the consequences of such a vulnerability. ### Attack Path 1. The Agent starts the Skill with an attacker-controlled or compromised URL. 2. Chromium launches with `--no-sandbox`. 3. The page delivers content that exploits a Chromium renderer or browser component vulnerability. 4. Because the normal sandbox boundary is disabled, exploit code may execute with the operating-system privileges of the Chromium process. 5. The attacker can access resources available to the account running the Skill. ### Impact Assessment A successful browser exploit could obtain the privileges of the Skill's operating-system account. This may permit access to that user's files, environment, browser session data, network access, and other processes or services available to the account. The code does not ...[truncated 176 chars]
Remediation
## Remediation Suggestions - Remove `--no-sandbox` and run Chromium under a dedicated, unprivileged operating-system account. - Ensure user namespaces and the Chromium sandbox helper are correctly configured. - Refuse to start as root unless execution occurs inside a hardened, disposable container. - If sandbox disabling is unavoidable, require an explicit opt-in option rather than applying it unconditionally. - Isolate the browser with a read-only filesystem, restricted network policy, dropped Linux capabilities, seccomp/AppArmor controls, and no access to host credentials. - Keep Chromium updated and document the residual risk associated with opening untrusted websites.

T09 · Insecure Skill Coding Practices

Warning
Location
skill.py:91
Finding
Persisted PIDs Are Terminated Without Process Identity Validation## Vulnerability Details **File Location**: `skill.py:17-29, 91-109` **Vulnerability Type**: Unsafe process management using stale identifiers **Risk Level**: Medium ```python STATE_PATH = Path.home() / ".cache" / "virtual-desktop-browser" / "state.json" STATE_PATH.parent.mkdir(parents=True, exist_ok=True) def _load_state(): if STATE_PATH.exists(): return json.loads(STATE_PATH.read_text()) return {"display": None, "xvfb_pid": None, "chrome_pid": None} def _save_state(state): STATE_PATH.write_text(json.dumps(state, ensure_ascii=False, indent=2)) def _kill_pid(pid): if not pid: return try: os.kill(pid, signal.SIGTERM) time.sleep(0.3) os.kill(pid, 0) os.kill(pid, signal.SIGKILL) except ProcessLookupError: pass except Exception: pass def browser_stop(): state = _load_state() _kill_pid(state.get("chrome_pid")) _kill_pid(state.get("xvfb_pid")) new_state = {"display": None, "xvfb_pid": None, "chrome_pid": None} _save_state(new_state) return {"status": "stopped"} ``` ### Technical Analysis Process identifiers are stored in a persistent JSON file and later passed directly to `os.kill`. The implementation does not verify that a recorded PID still belongs to the Chromium or Xvfb process originally launched by the Skill. PIDs are reusable. If the Skill or host terminates unexpectedly, its state file can retain obsolete identifiers. The operating system may subsequently assign one of those identifiers to an unrelated process. Calling `browser_stop()` would then send `SIGTERM`, followed by `SIGKILL`, to that unrelated process. The implementation also suppresses all non-`ProcessLookupError` exceptions, making failures and unexpected termination behavior difficult to detect. This is not a cross-session backdoor or startup persistence mechanism; the persisted file only records runti ...[truncated 1224 chars]
Remediation
## Remediation Suggestions - Store process start times and expected executable identities alongside each PID. - Before signaling, verify the process UID, `/proc/<pid>/exe`, command line, and start time against the recorded values. - Treat a failed identity check as stale state and remove the record without sending a signal. - Launch Chromium and Xvfb in a dedicated process group and terminate only the verified group. - Use retained `subprocess.Popen` handles when lifecycle management occurs within one process. - Write state atomically with restrictive permissions and validate the JSON schema and PID types when loading it. - Replace broad exception suppression with explicit error handling and security-relevant logging.

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Third-Party Python Dependencies Are Not Reproducibly Pinned## Vulnerability Details **File Location**: `requirements.txt:1-5` **Vulnerability Type**: Mutable dependency resolution **Risk Level**: Medium ```text pyautogui>=0.9.54 pillow>=10.0.0 opencv-python>=4.8.0 pygetwindow>=0.0.9 pyperclip>=1.8.2 ``` ### Technical Analysis Every Python dependency uses an open-ended lower-bound constraint. Consequently, `pip install -r requirements.txt` may install future releases that were not present during this audit. No lock file or package hashes constrain the resolved artifacts. This makes installations non-reproducible and increases supply-chain exposure. A future compromised release, maliciously replaced distribution artifact, or incompatible update could execute during installation or alter the runtime behavior of the Skill. There is no evidence in the reviewed project that the currently named packages are typosquatted or malicious. The finding concerns unsafe dependency resolution rather than a confirmed malicious dependency. ### Attack Path 1. A dependency account, release pipeline, package index, or distribution artifact is compromised, or a future release introduces malicious behavior. 2. A user follows the documented `pip install -r requirements.txt` command. 3. Because only minimum versions are specified, the package installer resolves the new, unaudited release. 4. Malicious installation hooks or imported package code execute with the privileges of the installation or Skill process. 5. The compromised dependency can access data and resources available to that account. ### Impact Assessment A malicious dependency could execute arbitrary Python code with the privileges of the user installing or running the Skill. Depending on the environment, this could expose files, screenshots, browser data, credentials available to the process, and network access. If dependencies are installed with administrative privileges, system-wide files and environments may a ...[truncated 100 chars]
Remediation
## Remediation Suggestions - Pin every direct and transitive dependency to a reviewed exact version. - Generate and commit a lock file using a tool such as `pip-tools`, Poetry, or an equivalent reproducible dependency manager. - Require cryptographic hashes for downloaded artifacts, such as with `pip install --require-hashes`. - Install only from a trusted package index and disable unneeded fallback indexes. - Run dependency vulnerability and provenance scanning in continuous integration. - Review and deliberately update locked dependencies on a controlled schedule. - Install dependencies in an isolated virtual environment as an unprivileged user rather than using system-wide administrative installation.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (29)

Natural-Language Policy Violations

High
Confidence
97% confidence
Finding
The document markets the skill as ideal for anti-bot sites and emphasizes human-like automation in a visible browser, which strongly suggests use to evade bot-detection and platform safeguards. That context makes the capability materially more dangerous because it facilitates deceptive automation against third-party services and can be combined with screenshot and input control for abuse at scale.

Chaining Abuse

High
Category
Tool Misuse
Content
if missing:
        raise RuntimeError(
            "Missing system dependencies: " + ", ".join(missing) +
            "\nInstall with: sudo apt-get update && sudo apt-get install -y xvfb chromium-browser"
        )
Confidence
75% confidence
Finding
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
xvfb_proc = subprocess.Popen(xvfb_cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    time.sleep(1)

    env = os.environ.copy()
    env["DISPLAY"] = disp
    chrome_cmd = [
        "chromium-browser",
Confidence
60% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Rp1

Medium
Category
MCP Rug Pull
Confidence
82% confidence
Finding
The README instructs users to install the skill via `npx skills add` from a GitHub URL without pinning to a specific commit, tag, or immutable release. That creates a supply-chain risk because future changes to the referenced repository or resolver behavior could cause users to fetch and run different code than was originally reviewed.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill advertises screenshot capture of the browser display but does not warn that screenshots may include secrets, personal data, session contents, or other sensitive on-screen information. In this skill's context, screenshotting is a core feature for GUI automation, so omission of a privacy warning increases the chance of accidental collection and exfiltration of sensitive data.

Missing User Warnings

Medium
Confidence
81% confidence
Finding
The documentation promotes keyboard automation into the active focused element without warning that it may submit forms, send messages, alter account settings, or trigger destructive shortcuts in the browser session. Because this skill is specifically designed to mimic human GUI interaction on live sites, unintended keystrokes could directly impact external accounts and data integrity.

Missing User Warnings

Medium
Confidence
85% confidence
Finding
The examples explicitly encourage use against anti-bot-protected sites and include screenshotting, but provide no warning about privacy, account risk, terms-of-service violations, or unintended interaction with real online services. In context, the skill is purpose-built for human-like automation on bot-resistant sites, which makes misuse more plausible and raises the security and abuse risk beyond a generic GUI automation tool.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill exposes capabilities consistent with shell, file read/write, and environment access but does not declare any explicit tool scope or permission boundaries. For a GUI automation skill that launches Xvfb and Chromium and installs system packages, this increases the risk of over-privileged execution, making it easier for downstream workflows to use the skill for arbitrary command execution, filesystem access, or secret exposure beyond the stated browser automation purpose.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding
The documentation instructs users to install the skill via `npx skills add` from a GitHub URL without any pinned version, commit, or integrity control. That creates a supply-chain risk: future upstream changes or a compromised repository could deliver different code than was originally reviewed.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This skill explicitly supports screenshots, pixel inspection, typing, clicking, and window activation, but the documentation does not warn that these capabilities can capture secrets or interact with authenticated sessions. In context, GUI automation against live sites raises risk of credential exposure, sensitive data collection, and unintended actions on behalf of the user.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding
The documentation instructs users to install the skill directly from a GitHub URL via `npx skills add` without pinning to a specific immutable version, tag, or commit. That creates a supply-chain risk: if the upstream repository changes or is compromised, later installs may pull different code than originally reviewed.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This skill explicitly supports screen capture, pixel inspection, window focus, and human-like GUI automation against live sites, but the documentation does not warn about capturing sensitive on-screen data or the ability to perform unintended actions in authenticated sessions. In this context, omission of privacy and integrity warnings increases the chance of misuse, accidental data exposure, and unsafe operation by users who may not realize the sensitivity of screenshots and simulated input.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The description promotes human-like mouse and keyboard automation for anti-bot-resistant sites but does not warn that these actions can operate inside authenticated sessions and perform real state-changing actions such as posting, purchasing, messaging, or account changes. In this skill's context, omission of those warnings is more dangerous because the entire purpose is realistic GUI interaction with live websites.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
The documentation instructs users to install the skill via `npx skills add` from a remote GitHub source without any version pinning or immutable reference. This creates a supply-chain risk: future upstream changes, account compromise, or repo takeover could cause users to fetch and run different code than expected.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill documents full-screen and region screenshot capture as Base64 output but provides no warning about collecting sensitive on-screen content such as credentials, personal data, or authenticated session information. In a GUI browser automation context, screenshots can easily expose private data and become exfiltration material if logged, stored, or forwarded.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
if missing:
        raise RuntimeError(
            "Missing system dependencies: " + ", ".join(missing) +
            "\nInstall with: sudo apt-get update && sudo apt-get install -y xvfb chromium-browser"
        )
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The skill silently starts a GUI environment and a browser capable of interacting with external websites, which materially increases the agent's ability to perform high-impact automated actions. In this skill's context—explicitly targeting bot-resistant sites and GUI simulation—the lack of disclosure and safeguards makes misuse more dangerous, not less.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
disp = display or _find_free_display()

    xvfb_cmd = ["Xvfb", disp, "-screen", "0", f"{FIXED_WIDTH}x{FIXED_HEIGHT}x{FIXED_DEPTH}"]
    xvfb_proc = subprocess.Popen(xvfb_cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    time.sleep(1)

    env = os.environ.copy()
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
f"--window-size={FIXED_WIDTH},{FIXED_HEIGHT}",
    ]
    chrome_cmd.append(url or "about:blank")
    chrome_proc = subprocess.Popen(chrome_cmd, env=env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

    state = {
        "display": disp,
Confidence
92% confidence
Finding
The Chromium process is launched with the '--no-sandbox' flag, which disables an important browser isolation boundary. If a malicious page exploits the browser, the lack of sandboxing can significantly increase the impact by making host compromise or lateral access easier inside the agent environment.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The stop routine forcefully terminates stored PIDs without validating that they still belong to the expected child processes. If the state file becomes stale or is tampered with, this can kill unintended local processes, creating a denial-of-service condition.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This function captures screenshots and returns raw image data from the virtual desktop without any consent, disclosure, or output filtering. In an automation context, screenshots may contain credentials, personal data, session contents, or other sensitive visual information that can be exfiltrated through the tool response.

Missing User Warnings

Medium
Confidence
85% confidence
Finding
Automated typing allows arbitrary text injection into the GUI session, including passwords, messages, search terms, or destructive commands in web apps or terminal-like browser pages. Without disclosure, confirmation, or destination validation, this can be abused for impersonation, unauthorized transactions, or data manipulation.

Unpinned Dependencies

Low
Category
Supply Chain
Content
pyautogui>=0.9.54
pillow>=10.0.0
opencv-python>=4.8.0
pygetwindow>=0.0.9
Confidence
98% confidence
Finding
The dependency is specified with a lower bound only, so builds may resolve to different versions over time, including versions with newly introduced vulnerabilities or breaking behavior. In a GUI automation skill that drives a browser and interacts with the desktop, supply-chain instability is undesirable because compromised or vulnerable packages could affect host interaction capabilities.

Unpinned Dependencies

Low
Category
Supply Chain
Content
pyautogui>=0.9.54
pillow>=10.0.0
opencv-python>=4.8.0
pygetwindow>=0.0.9
pyperclip>=1.8.2
Confidence
99% confidence
Finding
Pillow is unpinned, which prevents reproducible installs and makes it impossible to know which version will be deployed. Given Pillow's history of security advisories, leaving it as ">=" increases the chance of resolving to a vulnerable or unexpected release in different environments.

Unverifiable Dependency: pillow has 16 known advisory(ies) (CVE-2016-2533 (Pillow buffer overflow in ImagingPcdDecode); CVE-2023-50447 (Arbitrary Code Execution in Pillow); CVE-2021-27922 (Pillow Uncontrolled Resource Consumption) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
96% confidence
Finding
The manifest does not pin Pillow, so there is no way to verify whether deployment will use a version affected by known Pillow advisories. Since this skill likely processes screenshots and image data in an automated browser workflow, a vulnerable Pillow build could be exposed to malicious or malformed image content and increase exploitability.

Static analysis

No suspicious patterns detected.