Back to skill

Security audit

Clipboard Manager

Security checks for vulnerabilities and agentic risk

Overview

This clipboard-history skill does what it claims, but it persistently stores potentially sensitive clipboard contents in plaintext without clear warning or access-control hardening.

Review this before installing if you copy passwords, API keys, private messages, financial details, or recovery codes. Use it only on a trusted single-user machine, clear the history regularly, and prefer a hardened version that warns before monitoring, stores data with restrictive permissions or encryption, filters likely secrets, and supports expiration.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/clipboard.py:14
Finding
Clipboard History Is Persisted in Plaintext Without Enforced Owner-Only Permissions## Vulnerability Details **File Location**: `scripts/clipboard.py`, lines 14–25 and 76–94 **Vulnerability Type**: Plaintext storage of potentially sensitive clipboard data with inherited filesystem permissions **Risk Level**: Medium ### Vulnerable Code ```python DATA_FILE = os.path.expanduser("~/.clipboard_history.json") MAX_ITEMS = int(os.environ.get("CLIPBOARD_MAX", "100")) def load_history(): if os.path.exists(DATA_FILE): with open(DATA_FILE, "r", encoding="utf-8") as f: return json.load(f) return {"items": [], "pinned": []} def save_history(data): with open(DATA_FILE, "w", encoding="utf-8") as f: json.dump(data, f, indent=2) ``` ```python if content and content != last_content and len(content.strip()) > 0: last_content = content # Add to history item = { "content": content[:500], "time": datetime.now().isoformat(), "type": "text" } # Check whether it already exists existing = [i for i in data["items"] if i["content"] == content] if not existing: data["items"].insert(0, item) # Limit item count if len(data["items"]) > MAX_ITEMS: data["items"] = data["items"][:MAX_ITEMS] save_history(data) ``` ### Technical Analysis Monitor mode captures each new nonempty clipboard value and writes up to 500 characters to the predictable file `~/.clipboard_history.json`. Clipboard data frequently contains passwords, API tokens, one-time codes, private messages, financial information, and other sensitive material. The history is stored as unencrypted JSON. The file is opened with the standard `open(..., "w")` operation, so its creation permissions depend on the process umask rather than an explicitly enforced owner-only mode such as `0600`. If the process uses a permissive umask, the resulting file may be readable by other local users. If the file already exis ...[truncated 1803 chars]
Remediation
## Remediation Suggestions 1. Store history in a dedicated private directory created with mode `0700`. 2. Create the history file atomically with owner-only mode `0600`, rather than relying on the process umask. 3. Validate and correct the permissions of an existing history file before reading or writing it, rejecting symbolic links and unexpected file types. 4. Use atomic replacement to avoid partial writes while preserving restrictive permissions. 5. Consider encrypting persisted clipboard history with an operating-system credential store or a user-controlled encryption key. 6. Warn users clearly that monitor mode records clipboard content and may capture credentials or other secrets. 7. Add configurable exclusions for likely secrets, maximum retention periods, automatic expiration, and a nonpersistent monitoring mode. 8. Ensure that clearing history securely removes all retained and pinned entries, while documenting that copies may still exist in filesystem snapshots or backups. A hardened implementation should use secure file creation primitives such as `os.open()` with `O_CREAT`, `O_WRONLY`, and an explicit mode of `0o600`, followed by verification with `os.fstat()`. Existing files should be changed to `0600` where appropriate before use.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (11)

Missing User Warnings

High
Confidence
97% confidence
Finding
This skill stores clipboard history and even gives an example of searching for entries containing '密码', but it does not warn users that clipboard contents commonly include passwords, tokens, personal data, or other secrets. In this context, missing disclosure and retention guidance is dangerous because the skill's core function is persistent collection and retrieval of highly sensitive transient data.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill documents shell execution and clipboard history persistence but does not declare any explicit tool scope such as permissions or allowed-tools. That creates an authorization and transparency gap: an agent may be induced to read environment variables, read or write local files, or invoke shell commands without the user having a clearly declared security boundary.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The description, triggers, and usage documentation are entirely in Chinese, which effectively constrains the skill to a specific language without stating that this is intentional or optional. The file does not offer an alternate language or note that the skill is designed specifically for a Chinese-speaking context.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The trigger phrases are generic terms like '剪贴板' and '剪贴板历史', which are likely to appear in normal conversation unrelated to intentionally invoking this skill. Broad activation increases the chance of accidental execution of clipboard-related commands, which is especially risky because clipboard history may contain sensitive material.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
Clipboard contents are written to `~/.clipboard_history.json` without any disclosure, access control hardening, or protection of sensitive entries. If the host is shared, backed up, synced, or later compromised, persisted clipboard history can expose secrets far beyond the user's original intent to copy them.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"""获取剪贴板内容"""
    try:
        # Linux
        result = subprocess.run(["xclip", "-selection", "clipboard", "-o"], 
                              capture_output=True, text=True, timeout=2)
        if result.returncode == 0:
            return result.stdout
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
try:
        # macOS
        result = subprocess.run(["pbpaste"], capture_output=True, text=True, timeout=2)
        if result.returncode == 0:
            return result.stdout
    except:
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
"""设置剪贴板"""
    try:
        # Linux
        subprocess.run(["xclip", "-selection", "clipboard", "-i"], 
                     input=text.encode(), check=True)
        return True
    except:
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
try:
        # macOS
        subprocess.run(["pbcopy"], input=text.encode(), check=True)
        return True
    except:
        pass
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The monitor continuously captures clipboard contents and persists them to disk, which can silently collect passwords, tokens, private messages, and other secrets that users copy temporarily. In a clipboard-history tool this behavior is contextually expected, but it remains dangerous because there is no consent flow, sensitivity filtering, or clear warning before persistent collection begins.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
The file presents its description and multiple user-facing strings in Chinese, with no mechanism for users to select another language or locale. This can violate language/locale policy when a skill imposes one language by default without opt-in.

Static analysis

No suspicious patterns detected.