Back to skill

Security audit

Screen Vision

Security checks for vulnerabilities and agentic risk

Overview

The skill’s desktop-control purpose is coherent, but it needs Review because its safeguards and headless remote-desktop setup are unsafe for a tool that can see and operate a user’s screen.

Install only in a disposable or tightly controlled environment until the VNC password/listener, confirmation enforcement, endpoint validation, screenshot logging, and installer secret handling are fixed. Do not use it on screens containing passwords, private documents, financial accounts, or authenticated business tools unless you fully trust the configured vision provider and network exposure.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/core/run_task.py:158
Finding

Confirmation-required actions are executed without user approval

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/setup/setup-linux.sh:69
Finding

Headless setup exposes VNC with a predictable default password

Content
View full analysis
~/.vnc/passwd chmod 600 ~/.vnc/passwd echo "[6/6] Creating start/stop scripts..." cat > /usr/local/bin/sv-start << 'SCRIPT' #!/bin/bash # Start virtual desktop for screen-vision echo "Starting VNC server on display :1..." vncserver :1 -geometry 1024x768 -depth 24 -localhost no 2>/dev/null || \ vncserver :1 -geometry 1024x768 -depth 24 ``` ### Technical Analysis Every headless installation receives the same hard-coded VNC password, `screen123`. The generated startup script first invokes VNC with `-localhost no`, allowing non-local network connections. Restricting the password file to mode `0600` only protects the stored credential from local file reads. It does not mitigate remote authentication with the publicly known password. The remote desktop capability is necessary for headless use, but a universal credential and external binding exceed a secure minimum-privilege configuration. ### Attack Path 1. A user runs the Linux setup in headless mode. 2. The script installs the fixed VNC password `screen123`. 3. The user launches the generated `sv-start` command. 4. VNC binds in a mode that accepts non-local connections. 5. An attacker with network access to the VNC port connects using the known password. 6. The attacker gains interactive control of the virtual desktop. ### Impact Assessment Successful exploitation grants remote GUI access to the VNC session. The attacker can view the desktop, capture sensitive information, control mouse and keyboard input, access authenticated applications, and potentially execute terminal commands with the privileges of the VNC user. ]]>
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/vision/analyze.py:84
Finding

Screenshots and bearer credentials can be transmitted to an unvalidated endpoint

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
install.sh:84
Finding

Installer API-key interpolation permits Python code injection and weak secret handling

Content
View full analysis
/dev/null; then python3 -c " import json with open('$CONFIG_FILE') as f: c = json.load(f) c['vision']['apiKey'] = '$API_KEY' with open('$CONFIG_FILE', 'w') as f: json.dump(c, f, indent=2) " fi echo " ✅ API Key 已配置" ``` ### Technical Analysis `API_KEY` and `CONFIG_FILE` are directly interpolated into source passed to `python3 -c`. Shell quoting does not safely encode those values as Python string literals. An API-key value containing a single quote followed by valid Python syntax can terminate the intended string and inject additional Python statements. The API key is also accepted as a command-line argument, which may expose it through shell history or process inspection. The generated `config.json` is written without explicitly applying restrictive permissions. ### Attack Path 1. A user is given an attacker-crafted value represented as a vision API key. 2. The user invokes `install.sh --api-key `. 3. Shell expansion inserts the value into the Python source. 4. The crafted quote terminates `c['vision']['apiKey'] = '...'`. 5. Injected Python executes during installation. 6. The injected code runs with the privileges of the account invoking the installer. ### Impact Assessment Exploitation permits arbitrary Python code execution in the installer context. The attacker can read or modify user-accessible files, extract credentials, alter the installed Skill, or execute other programs. If the installer is run with elevated privileges, the impact expands to those privileges. ]]>
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/platform/screenshot.sh:22
Finding

Screenshot fallback interpolates path and display values into executable Python source

Content
View full analysis
/dev/null && return 0 ``` ```bash MINGW*|MSYS*|CYGWIN*) python3 -c " import pyautogui pyautogui.screenshot('$OUTPUT') " 2>/dev/null && return 0 ``` ### Technical Analysis The output path and display identifier are inserted directly into Python string literals. Shell double quotes allow variable expansion, but do not encode the expanded values for Python. A value containing a single quote and Python syntax can escape the intended string. On Linux, exploitation requires reaching the Python fallback after the primary screenshot tools fail. On the Windows-compatible branch, the vulnerable Python code is the normal screenshot implementation. Within the main task runner, screenshot paths are fixed, reducing direct exposure through that path. The screenshot script is nevertheless documented as a standalone interface accepting caller-supplied output and display arguments. ### Attack Path 1. An attacker influences the output path or display argument supplied to `screenshot.sh`. 2. The value contains syntax that terminates the Python string literal. 3. On Linux, the primary `scrot` and ImageMagick capture attempts fail, causing the fallback to execute; on the Windows-compatible branch, the Python code executes directly. 4. `python3 -c` parses the interpolated value as part of its program. 5. Attacker-controlled Python statements execute with the privileges of the caller. ### Impact Assessment Successful exploitation provides arbitrary code execution as the user running the screenshot utility. This can expose screen content, user files, environ ...[truncated 72 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/setup/setup-linux.sh:39
Finding

Runtime installers fetch unpinned third-party dependencies

Content
View full analysis
/dev/null || pip install --quiet Pillow numpy ``` ```bash # scripts/setup/setup-mac.sh echo "[2/3] Installing Python dependencies..." pip3 install --quiet Pillow numpy 2>/dev/null || pip install --quiet Pillow numpy ``` ```python # scripts/setup/setup-win.py subprocess.run([sys.executable, "-m", "pip", "install", "--quiet", "pyautogui", "Pillow", "numpy"], check=False) ``` ### Technical Analysis The setup scripts resolve mutable package names from the active Python package index without pinned versions, hashes, or a lock file. The effective installed code can therefore change after the Skill has been reviewed. No evidence in the audited source shows deliberate dependency confusion, typosquatting, or a known malicious package. The vulnerability is the absence of reproducible and integrity-checked dependency resolution, which increases exposure to upstream compromise, malicious mirrors, or incompatible future releases. ### Attack Path 1. A user runs one of the setup scripts. 2. `pip` contacts the configured package index or mirror. 3. The resolver selects the latest package versions available at installation time. 4. A compromised account, index, mirror, or distribution channel supplies a malicious release. 5. Package installation or later import executes attacker-controlled code. ### Impact Assessment A compromised dependency can execute with the installer or Skill process privileges. It may access screenshots, desktop input, configuration files, API credentials, and user data. The scope depends on whether installation occurs as a normal user or with elevated ...[truncated 16 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/core/run_task.py:97
Finding

User-configured task limits are ignored in favor of hard-coded constants

Content
View full analysis
MAX_DURATION_MIN: issues.append(f"Task exceeded {MAX_DURATION_MIN}min timeout") if action_count > MAX_ACTIONS: issues.append(f"Task exceeded {MAX_ACTIONS} action limit") return { "within_limits": len(issues) == 0, "issues": issues } ``` ### Technical Analysis The runner reads `max_duration_min` and `max_actions` from configuration but never passes those values to `check_task_limits()`. The checker instead compares against module constants of five minutes and 100 actions. As a result, stricter operator-configured limits are silently ignored. The local `max_duration` and `max_actions` variables only affect other limited logic; notably, `max_actions` is also used as part of API retry handling, but not as the main action boundary. ### Attack Path 1. An operator configures a strict duration or action limit to constrain automation. 2. The task runner loads and stores those values. 3. During each iteration, it invokes `check_task_limits()` without the configured limits. 4. The checker uses the hard-c ...[truncated 485 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (48)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · README.md (reported line 203)May include surrounding context.

md
## 🔒 安全机制

- ❌ **自动拦截**:`rm -rf /`、格式化磁盘、`shutdown`、`drop database` 等
- ⚠️ **需确认**:涉及删除、sudo、支付等敏感操作
- ⏱️ **超时保护**:最长 5 分钟 / 100 步自动停止
- 📸 **操作日志**:所有截图保存到 `/tmp/screen-vision/logs/`

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · README.md (reported line 203)May include surrounding context.

md
## 🔒 安全机制

- ❌ **自动拦截**:`rm -rf /`、格式化磁盘、`shutdown`、`drop database` 等
- ⚠️ **需确认**:涉及删除、sudo、支付等敏感操作
- ⏱️ **超时保护**:最长 5 分钟 / 100 步自动停止
- 📸 **操作日志**:所有截图保存到 `/tmp/screen-vision/logs/`

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger is extremely broad, covering generic requests like opening apps, browsing websites, taking screenshots, and 'operate/control computer,' which overlaps with many normal user prompts. In practice this can cause the skill to activate in contexts involving sensitive desktop state, credentials, private documents, or unintended remote control, expanding attack surface and increasing the risk of unauthorized actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill states that screenshots are analyzed by an external vision API, but it does not prominently warn users that screen contents and task text may be transmitted off-device to third-party providers. Because screenshots can contain secrets, personal data, tokens, emails, or financial information, the missing disclosure materially increases privacy and data-exfiltration risk.

Content

No source excerpt is available for this finding.

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
98% confidence
Finding

The screenshot command is built as a shell string and executed with os.system(), while display_id can come from CLI arguments or environment-derived configuration. This creates a command-injection surface where a crafted display value or path-containing metacharacters could execute arbitrary shell commands in the host context.

Content

Scanner excerpt · scripts/core/run_task.py (reported line 34)May include surrounding context.

python
cmd = f"bash {script} {output_path}"
    if display_id:
        cmd = f"SV_DISPLAY={display_id} {cmd}"
    ret = os.system(cmd)
    return ret == 0 and os.path.exists(output_path)

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
84% confidence
Finding

Copying the entire process environment into a child process can unnecessarily expose secrets such as API keys, tokens, proxy credentials, and cloud metadata to downstream components. In a skill that orchestrates external scripts and remote APIs, broad environment propagation expands the blast radius if a child process is compromised or logs its environment.

Content

Scanner excerpt · scripts/core/run_task.py (reported line 63)May include surrounding context.

python
cmd.extend(["--x2", str(action.get("x2", 0))])
        cmd.extend(["--y2", str(action.get("y2", 0))])
    
    env = os.environ.copy()
    if display_id:
        env["SV_DISPLAY"] = display_id
        env["DISPLAY"] = display_id

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
85% confidence
Finding

The code copies screenshots using os.system() with shell interpolation. While the current paths are mostly internally constructed, using the shell for file operations is unsafe and can become exploitable if path assumptions change, symlinks are abused, or surrounding state is attacker-controlled.

Content

Scanner excerpt · scripts/core/run_task.py (reported line 220)May include surrounding context.

python
# Save screenshot log
        if safety_config.get("screenshot_log", True):
            log_ss = os.path.join(log_dir, f"step_{action_count:03d}.png")
            os.system(f"cp {ss_path} {log_ss} 2>/dev/null")
        
        # Wait and take new screenshot
        time.sleep(wait_after)

Env Variable Harvesting

High
Category
Data Exfiltration
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.

Content

Scanner excerpt · scripts/platform/execute.py (reported line 40)May include surrounding context.

python
def run_cmd(cmd, display=None):
    """Run command with optional DISPLAY env."""
    import os
    env = os.environ.copy()
    if display and get_os() == "linux":
        env["DISPLAY"] = display
    result = subprocess.run(cmd, capture_output=True, text=True, env=env, timeout=10)

Unvalidated Output Injection

High
Category
Output Handling
Confidence
96% confidence
Finding

The Python fallback is built by interpolating shell variables directly into a Python -c string, so attacker-controlled values such as OUTPUT or DISPLAY_ID can break out of the intended quoting and inject arbitrary Python code. In a skill that performs desktop automation and may run with access to a user's session, this can lead to arbitrary command execution and compromise of the local environment.

Content

Scanner excerpt · scripts/platform/screenshot.sh (reported line 26)May include surrounding context.

sh
# Fallback: use Python
            python3 -c "
import subprocess
subprocess.run(['DISPLAY', '$display', 'scrot', '-z', '-overwrite', '$OUTPUT'], env={'DISPLAY': '$display', 'PATH': '/usr/bin:/bin'})
" 2>/dev/null && return 0
            
            echo "ERROR: No screenshot tool available on Linux" >&2

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script silently provisions remote desktop access by writing VNC credentials and installing executable start/stop helpers under /usr/local/bin, but gives no explicit warning that this creates a remotely reachable control plane for the machine. In a screen-control skill, this is especially dangerous because it expands from local automation to persistent remote GUI access, increasing the attack surface substantially.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
100% confidence
Finding

The script sets a hardcoded default VNC password ('screen123') and stores its VNC-hashed form automatically, meaning every installation can share the same easily guessed credential. Because the skill is explicitly designed for desktop control, compromise of this password can grant full interactive control of the host's GUI session.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

The stop script reads a PID from a predictable file in /tmp and passes it directly to 'kill' without validating ownership, file type, or whether the PID belongs to the expected websockify process. A local attacker could tamper with /tmp/sv-novnc.pid or exploit symlink/race conditions to cause termination of unintended processes run by the same user, or by root if the helper is executed with elevated privileges.

Content

Scanner excerpt · scripts/setup/setup-linux.sh (reported line 98)May include surrounding context.

sh
echo "Stopping screen-vision desktop..."
vncserver -kill :1 2>/dev/null
kill $(cat /tmp/sv-novnc.pid 2>/dev/null) 2>/dev/null
rm -f /tmp/sv-novnc.pid
echo "Stopped."
SCRIPT
    chmod +x /usr/local/bin/sv-stop

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

The external API endpoint itself is expected functionality for a vision skill, but the README shows configuration for a third-party endpoint without an adjacent privacy/security warning. Given that the tool captures full-screen images, using an external provider can expose sensitive desktop content if users are not clearly informed.

Content

Scanner excerpt · README.md (reported line 90)May include surrounding context.

json
{
  "vision": {
    "baseUrl": "https://api.siliconflow.cn/v1",
    "apiKey": "YOUR_API_KEY",
    "model": "Qwen/Qwen3-VL-32B"
  }

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

The environment-variable example encourages configuring an external vision endpoint, which is normal for the product, but it still represents external transmission of potentially sensitive screenshots. In the context of a computer-control skill, this is more dangerous than ordinary API use because the captured screen may include high-value secrets from unrelated applications.

Content

Scanner excerpt · README.md (reported line 101)May include surrounding context.

bash
export SV_VISION_API_KEY=your_api_key
export SV_VISION_BASE_URL=https://api.siliconflow.cn/v1
export SV_VISION_MODEL=Qwen/Qwen3-VL-32B

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README promotes sending screenshots to 'all OpenAI-compatible vision APIs' but does not clearly warn that on-screen content may be transmitted to third-party providers. In a desktop-control skill, screenshots can contain passwords, messages, financial data, or proprietary information, so omission of this disclosure meaningfully increases privacy and data-handling risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README states that all screenshots are saved under /tmp/screen-vision/logs/ but does not warn that these logs may retain sensitive on-screen data locally. Because this skill continuously captures the desktop, the saved images may include secrets, personal data, and enterprise information that remain accessible to other local users or later processes depending on system configuration.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill advertises capabilities that imply shell execution, network access, environment-variable use, and file writes, but it declares no explicit tool scope or permission boundaries. For a desktop-control skill that can take screenshots, call external APIs, and execute platform commands, the absence of declared restrictions increases the chance of overbroad invocation and unintended access to sensitive local data or system functions.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
88% confidence
Finding

Autonomous decision-making in a screenshot-to-action loop is inherently risky for a desktop-control skill because the model can choose clicks, typing, navigation, and other actions based on imperfect visual interpretation. In this context, autonomy can lead to unintended data disclosure, destructive UI actions, or interaction with security-sensitive prompts unless tightly constrained and confirmed.

Content

Scanner excerpt · SKILL.md (reported line 5)May include surrounding context.

md
name: screen-vision
description: >
  AI screen vision and desktop computer control skill for OpenClaw.
  Let your AI agent see the screen, understand UI elements, and autonomously perform
  mouse and keyboard operations (click, type, scroll, drag) via a screenshot-analyze-action loop.
  Cross-platform: Linux (headless server with XFCE4+noVNC, or desktop), macOS (cliclick),
  Windows (pyautogui). Supports any OpenAI-compatible vision API (SiliconFlow, OpenAI,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The installer accepts an API key on the command line and writes it directly into config.json, creating a plaintext credential at rest without warning, permission hardening, or preference for safer secret sources. In the context of a desktop-control skill that can access vision APIs and potentially sensitive screenshots, compromise of that key could enable unauthorized API usage, billing abuse, and exposure of screen-derived data sent through the configured provider.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 48)May include surrounding context.

md
| 字段 | 说明 | 示例 |
|------|------|------|
| `baseUrl` | API 地址 | `https://api.siliconflow.cn/v1` |
| `apiKey` | API 密钥 | `sk-xxx...` |
| `model` | 视觉模型名称 | `Qwen/Qwen3-VL-32B` |

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/API_CONFIG.md (reported line 9)May include surrounding context.

md
| 字段 | 说明 | 示例 |
|------|------|------|
| `baseUrl` | API 地址 | `https://api.siliconflow.cn/v1` |
| `apiKey` | API 密钥 | `sk-xxx...` |
| `model` | 视觉模型名称 | `Qwen/Qwen3-VL-32B` |

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/API_CONFIG.md (reported line 25)May include surrounding context.

md
| 字段 | 说明 | 示例 |
|------|------|------|
| `baseUrl` | API 地址 | `https://api.siliconflow.cn/v1` |
| `apiKey` | API 密钥 | `sk-xxx...` |
| `model` | 视觉模型名称 | `Qwen/Qwen3-VL-32B` |

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/API_CONFIG.md (reported line 36)May include surrounding context.

md
| 字段 | 说明 | 示例 |
|------|------|------|
| `baseUrl` | API 地址 | `https://api.siliconflow.cn/v1` |
| `apiKey` | API 密钥 | `sk-xxx...` |
| `model` | 视觉模型名称 | `Qwen/Qwen3-VL-32B` |

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/API_CONFIG.md (reported line 68)May include surrounding context.

md
| 字段 | 说明 | 示例 |
|------|------|------|
| `baseUrl` | API 地址 | `https://api.siliconflow.cn/v1` |
| `apiKey` | API 密钥 | `sk-xxx...` |
| `model` | 视觉模型名称 | `Qwen/Qwen3-VL-32B` |

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/API_CONFIG.md (reported line 117)May include surrounding context.

md
{
  "vision": {
    "provider": "openai",
    "baseUrl": "https://api.openai.com/v1",
    "apiKey": "sk-your-key",
    "model": "gpt-5.4-mini"  // 替换为你使用的模型
  }

Static analysis

No suspicious patterns detected.