Back to skill

Security audit

Computer Use Notes

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent note-taking purpose, but it needs review because user note text is placed into a shell command and then stored persistently without clear consent or escaping.

Install only if you are comfortable with this skill retaining capability notes in local memory files. Before use, the command invocation should be changed to pass arguments without a shell, and stored notes should be escaped or clearly delimited as untrusted text with a way to view and delete them.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • 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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:16
Finding
Shell Command Injection Through Unsafe Note Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, line 16 **Vulnerability Type**: Shell command injection **Risk Level**: High ### Vulnerable Code ```text python3 skills/computer-use-notes/scripts/add_note.py --category <category> --note "<text>" ``` ### Technical Analysis The Skill instructs the agent to insert user-controlled note text directly into a shell command enclosed in double quotes. Double quotes do not prevent shell evaluation of command substitutions such as `$(...)` or backticks. Embedded quotation marks may also terminate the intended argument and expose additional shell syntax. If the agent follows this instruction through a shell-based execution tool, malicious note content can be interpreted by the shell before `add_note.py` or `argparse` receives it. The Python script's argument validation therefore does not mitigate this issue. ### Attack Path 1. An attacker submits a capability observation containing shell syntax, such as `$(touch /tmp/injected)`. 2. The agent extracts that observation as the note text. 3. Following `SKILL.md`, the agent constructs a command resembling: ```sh python3 skills/computer-use-notes/scripts/add_note.py --category can-do --note "$(touch /tmp/injected)" ``` 4. The shell evaluates the command substitution before starting the Python process. 5. The injected command executes with the same operating-system privileges as the agent or skill runner. 6. More consequential payloads could read or modify files accessible to that account or invoke other locally available programs. ### Impact Assessment Successful exploitation permits arbitrary command execution with the privileges of the process executing the Skill. The accessible scope includes files, environment variables, credentials, tools, and network resources available to that account. This issue does not independently provide privilege escalation, but its impact can be substantial when the agent runs with broad workspace or system ac ...[truncated 11 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not construct a shell command by interpolating the note into a command string. - Invoke the script through an argument-array API with shell processing disabled. Conceptually, use arguments equivalent to: ```python [ "python3", "skills/computer-use-notes/scripts/add_note.py", "--category", category, "--note", note, ] ``` - If the execution environment cannot guarantee argument-array invocation, pass the note through standard input or a securely created data file instead of embedding it in shell syntax. - Explicitly state in `SKILL.md` that `shell=True`, `sh -c`, `bash -c`, and equivalent shell wrappers must not be used with user-controlled note content. - Apply reasonable note length and character limits as defense in depth. Shell escaping alone should not be treated as the primary fix. - Add tests using quotation marks, command substitutions, backticks, semicolons, newlines, and leading hyphens to verify that every value is passed as inert data. ]]>

T02 · Agent Memory Poisoning

Warning
Location
scripts/add_note.py:31
Finding
Persistent Memory and Markdown Injection Through Untrusted Notes<![CDATA[ ## Vulnerability Details **File Location**: `scripts/add_note.py`, lines 31–37 and 47–58 **Vulnerability Type**: Persistent memory poisoning and Markdown injection **Risk Level**: Medium ### Vulnerable Code ```python def rebuild_board(entries): lines = ["# Computer Use 能力记录", ""] lines.append(f"更新于:{dt.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") lines.append("") for cat in CATS: lines.append(f"## {TITLES[cat]}") subset = [e for e in entries if e.get("category") == cat] if not subset: lines.append("- (暂无)") else: for e in subset[-200:]: lines.append(f"- [{e['time']}] {e['note']}") lines.append("") BOARD.write_text("\n".join(lines), encoding="utf-8") ``` ```python def main(): p = argparse.ArgumentParser() p.add_argument("--category", required=True, choices=CATS) p.add_argument("--note", required=True) args = p.parse_args() MEM_DIR.mkdir(parents=True, exist_ok=True) now = dt.datetime.now().strftime("%Y-%m-%d %H:%M:%S") item = {"time": now, "category": args.category, "note": args.note.strip()} with RAW.open("a", encoding="utf-8") as f: f.write(json.dumps(item, ensure_ascii=False) + "\n") entries = load_entries() rebuild_board(entries) ``` ### Technical Analysis The `--note` value is attacker-controlled and is stored without validation in the persistent JSONL log. It is then inserted verbatim into `memory/computer-use-notes.md`. Although JSON serialization protects the JSONL structure, it does not establish a trust boundary for the stored content. During Markdown generation, newlines, headings, links, embedded HTML, and prompt-like directives are preserved. A crafted note can therefore alter the apparent structure of the board or introduce instructions that later agents or automated consumers may mistake for trusted memory. The final Markdown output is a persistent state file rather than a transi ...[truncated 1514 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Treat all note values as untrusted data when storing, rendering, and later consuming them. - Reject or normalize control characters and impose a practical maximum note length. - Escape Markdown-sensitive characters and convert embedded line breaks before inserting notes into the board. Each note should remain within one clearly delimited list item. - If Markdown formatting is not required, render notes as escaped plain text or place them in a format that consumers parse strictly as data. - Add explicit markers around untrusted records and instruct all agent consumers that content inside those markers must never be interpreted as commands or policy. - Consider retaining immutable structured records as the source of truth and generating the display board only for human viewing. - Validate loaded JSONL entries against a schema, including the permitted category, timestamp format, note type, and length. - Add tests for multiline notes, headings, links, embedded HTML, code fences, and prompt-like directives to ensure they cannot alter board structure or become trusted instructions. ]]>
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (2)

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill instructs the agent to run a local Python script that appends data to persistent memory files, but it does not declare any tool scope or permissions boundary. That creates an authorization gap: a caller or orchestrator cannot easily determine in advance that the skill performs file writes, increasing the chance of unintended persistent modification or overbroad tool access.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill tells the agent to append user-provided observations to persistent log files, but it does not instruct the agent to notify the user that their input will be stored. This can cause silent retention of potentially sensitive operational notes, test results, or other user content, creating privacy and consent risks that are elevated because the storage is explicitly durable across sessions.

Static analysis

No suspicious patterns detected.