Back to skill

Security audit

Screenshot Ocr

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent screenshot OCR tool, but it handles clipboard images in a way that can leave sensitive screenshots in a predictable temporary file.

Review before installing. Use file-based OCR when possible, avoid running clipboard OCR on sensitive screenshots, and prefer a patched version that uses secure temporary files, removes clipboard-image artifacts after use, avoids shell=True, and pins dependencies. Install system packages only through your normal trusted package manager and avoid running Python package installs with administrator 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

Warning
Location
scripts/ocr.py:29
Finding

Predictable Shared Temporary File Enables Symlink and Stale-File Attacks

Content
View full analysis

Vulnerability Details

File Location: scripts/ocr.py, lines 29-38
Vulnerability Type: Insecure temporary-file handling
Risk Level: Medium

Vulnerable Code

python
subprocess.run(["xclip", "-selection", "clipboard", "-t", "image/png", "-o", "/tmp/clipboard.png"], 
              check=True, capture_output=True)
return "/tmp/clipboard.png"
python
subprocess.run(["pbpaste", ">", "/tmp/clipboard.png"], shell=True, capture_output=True)
if os.path.exists("/tmp/clipboard.png"):
    return "/tmp/clipboard.png"

Technical Analysis

The clipboard image is stored at the fixed, publicly predictable path /tmp/clipboard.png. The code does not securely create the file, verify its ownership or type, assign restrictive permissions, or remove it after OCR processing.

The macOS branch performs shell redirection to this predictable path. Shell redirection follows an existing symbolic link, so a local attacker can pre-create /tmp/clipboard.png as a symlink to another file writable by the OCR process. The target can then be overwritten with clipboard output when the victim invokes clipboard OCR.

The pbpaste operation is also executed without check=True. The subsequent logic only checks whether the path exists. Consequently, a failed clipboard operation can cause an old or attacker-prepared file at that path to be accepted and processed.

The Linux xclip invocation does not redirect captured standard output into the target file. Supplying /tmp/clipboard.png as an extra argument does not securely create or populate a temporary output file and may cause the command to fail, after which the vulnerable macOS fallback is attempted.

Attack Path

  1. A local attacker predicts the fixed /tmp/clipboard.png path.
  2. The attacker creates one of the following before the victim runs the tool:
    • A symbolic link from /tmp/clipboard.png to a file writable by the victim.
    • A regular file c ...[truncated 1132 chars]
Remediation
View remediation

Remediation Suggestions

  • Create temporary files with Python's tempfile module using unpredictable names and restrictive permissions.
  • Avoid shell=True and shell redirection. Capture command output directly and write it through an already-secured file descriptor.
  • Require successful command completion with check=True.
  • Confirm that generated output is a non-empty regular file owned by the current user before opening it.
  • Remove temporary clipboard data in a finally block, including after OCR failures.
  • Keep temporary file descriptors private and avoid reopening paths when possible, reducing time-of-check/time-of-use race conditions.

A safer implementation pattern is:

python
import os
import subprocess
import tempfile

path = None
try:
    result = subprocess.run(
        ["pbpaste"],
        check=True,
        capture_output=True,
    )
    with tempfile.NamedTemporaryFile(
        mode="wb",
        suffix=".png",
        delete=False,
    ) as output:
        output.write(result.stdout)
        path = output.name

    if not result.stdout:
        raise ValueError("Clipboard did not contain image data")

    return path
except Exception:
    if path and os.path.exists(path):
        os.unlink(path)
    return None

The caller should delete the returned file in a finally block after recognition completes.

T08 · Insecure Dependencies

Note
Location
SKILL.md:84
Finding

Unpinned Python Dependencies Permit Non-Reproducible Supply-Chain Resolution

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, line 84
Vulnerability Type: Unpinned third-party dependencies
Risk Level: Low

Vulnerable Code

bash
pip install pytesseract pillow

Technical Analysis

The documented installation command installs unconstrained versions of pytesseract and pillow from pip's configured package index. No reviewed versions, lock file, hashes, or trusted index URL are specified.

The package names are consistent with the declared OCR functionality, and the reviewed project contains no evidence that they are intentionally malicious. However, unconstrained resolution means that installations performed at different times can retrieve different code. A future compromised, malicious, or incompatible release could therefore be installed without any change to this project.

Package installation and imports may execute third-party code with the permissions of the installing or running user. Integrity pinning is consequently important even when the direct dependency names are legitimate.

Attack Path

  1. An attacker compromises a dependency release, its publisher account, or the package index used by the victim.
  2. A malicious or otherwise unsafe release becomes the version selected by unconstrained pip resolution.
  3. A user follows the documentation and runs pip install pytesseract pillow.
  4. pip downloads and installs the affected release.
  5. Third-party code may execute during installation or later when ocr.py imports and uses the package.

This path is contingent on compromise or unsafe configuration of the external dependency supply chain; the audited repository itself does not retrieve a known malicious package.

Impact Assessment

If the dependency source is compromised, code could run with the privileges of the user performing installation or executing the OCR utility. Potential scope includes:

  • Reading or modifying files accessible to that user.

...[truncated 409 chars]

Remediation
View remediation

Remediation Suggestions

  • Pin dependencies to reviewed versions rather than resolving unrestricted latest releases.
  • Maintain a lock or requirements file containing cryptographic hashes.
  • Install dependencies in a dedicated virtual environment without administrative privileges.
  • Explicitly use the intended trusted package index and disable unexpected extra indexes.
  • Periodically scan and update pinned dependencies after security review.
  • Prefer binary distributions from trusted sources where appropriate and verify the resolved dependency graph.

Example hardened installation workflow:

bash
python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install --require-hashes -r requirements.txt

The corresponding requirements.txt should contain reviewed exact versions and SHA-256 hashes for every resolved package.

Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (12)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

Using shell=True for a clipboard extraction helper is an unsafe pattern because it broadens the execution surface to the shell and normalizes a dangerous subprocess style. In a tool that handles user-controlled files and content, this increases the chance that later modifications introduce command injection or unexpected shell behavior; combined with writing to a predictable /tmp path, it also weakens overall safety.

Content

Scanner excerpt · scripts/ocr.py (reported line 37)May include surrounding context.

python
try:
        # 尝试使用 pbpaste (macOS)
        subprocess.run(["pbpaste", ">", "/tmp/clipboard.png"], shell=True, capture_output=True)
        if os.path.exists("/tmp/clipboard.png"):
            return "/tmp/clipboard.png"
    except:

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill documents shell execution and file-writing behavior but does not declare any explicit tool scope such as permissions or allowed-tools. That creates a mismatch between stated capabilities and enforced boundaries, increasing the risk that an agent may invoke shell commands or write files without clear restriction or user understanding.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger phrase "OCR" is extremely broad and likely to match many ordinary user requests outside the narrow intent of this skill. Overbroad activation can cause unintended invocation of shell/file-capable logic, increasing the chance of surprise execution, data handling, or privilege misuse in unrelated contexts.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The trigger phrase "屏幕识别" is ambiguous and does not clearly delimit whether it refers to OCR, screen analysis, or general visual inspection. In a skill that can process clipboard images and invoke local commands, ambiguous activation broadens the chance of accidental use on sensitive screen content.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

bash
# 安装 Tesseract(Linux)
sudo apt install tesseract-ocr tesseract-ocr-chi-sim

# macOS
brew install tesseract

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The file presents its docstrings, help text, and status messages primarily in Chinese, which imposes a specific language on users without any opt-in or alternative. The policy requires offering a language choice or clearly documenting and justifying a locale-specific constraint.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/ocr.py (reported line 21)May include surrounding context.

python
print("\n请安装:")
        print("  pip install pytesseract pillow")
        print("\n并安装 Tesseract:")
        print("  Ubuntu: sudo apt install tesseract-ocr tesseract-ocr-chi-sim")
        print("  macOS: brew install tesseract")
        return False

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill reads image data from the user's clipboard automatically and processes it without any explicit warning or confirmation. Clipboard contents often contain sensitive information, and in this OCR context the tool may extract and print or save secrets from screenshots, making the privacy risk more significant.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/ocr.py (reported line 29)May include surrounding context.

python
"""从剪贴板获取图片(Linux/macOS)"""
    try:
        # 尝试使用 xclip (Linux)
        subprocess.run(["xclip", "-selection", "clipboard", "-t", "image/png", "-o", "/tmp/clipboard.png"], 
                      check=True, capture_output=True)
        return "/tmp/clipboard.png"
    except:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
97% confidence
Finding

This call uses shell=True unnecessarily while attempting shell redirection, which introduces shell execution semantics into the tool. Even though the current arguments are constant, using shell=True with a sequence here is unsafe and error-prone, and in a future change could become command-injection reachable; it also mishandles clipboard extraction logic in a way that may execute unexpectedly under the shell.

Content

Scanner excerpt · scripts/ocr.py (reported line 37)May include surrounding context.

python
try:
        # 尝试使用 pbpaste (macOS)
        subprocess.run(["pbpaste", ">", "/tmp/clipboard.png"], shell=True, capture_output=True)
        if os.path.exists("/tmp/clipboard.png"):
            return "/tmp/clipboard.png"
    except:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/ocr.py (reported line 64)May include surrounding context.

python
"""复制到剪贴板"""
    try:
        # Linux
        subprocess.run(["xclip", "-selection", "clipboard"], input=text.encode(), check=True)
        print("✅ 已复制到剪贴板")
        return True
    except:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/ocr.py (reported line 72)May include surrounding context.

python
try:
        # macOS
        subprocess.run(["pbcopy"], input=text.encode(), check=True)
        print("✅ 已复制到剪贴板")
        return True
    except:

Static analysis

No suspicious patterns detected.