Back to skill

Security audit

Quick Capture

Security checks for vulnerabilities and agentic risk

Overview

This note-capture skill is mostly purpose-aligned, but it can write persistent notes to an installation-derived location that may be outside the intended note vault and it triggers on broad phrases.

Review or change the script before installing so the note vault root is explicitly configured and final paths are checked to remain inside that vault. Use the skill only if you are comfortable with it creating/appending persistent Markdown files, and be careful with casual phrases like '记一下' or '存一下' because the skill may treat them as instructions to save and restructure content.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/capture_note.py:62
Finding

Installation-Dependent Vault Root Can Cause Writes Outside the Intended Storage Scope

Content
View full analysis
tuple[Path, str]: vault_root = Path(__file__).resolve().parents[4] year = now.strftime("%Y") month = now.strftime("%Y-%m") date_stamp = now.strftime("%Y-%m-%d") journal_path = vault_root / "Journal" / year / month / f"{date_stamp}.md" journal_path.parent.mkdir(parents=True, exist_ok=True) ``` ```python def create_inbox_note(content: str, title: str, source_url: str, tags: list[str], now: datetime) -> tuple[Path, str]: vault_root = Path(__file__).resolve().parents[4] year = now.strftime("%Y") month = now.strftime("%Y-%m") date_stamp = now.strftime("%Y-%m-%d") clock_stamp = now.strftime("%H%M%S") note_title = title.strip() or derive_title_from_content(content) file_name = f"{date_stamp}--{clock_stamp}--{sanitize_path_segment(note_title)}.md" note_path = vault_root / "Inbox" / year / month / file_name note_path.parent.mkdir(parents=True, exist_ok=True) ``` ### Technical Analysis The script derives the note vault from a fixed ancestor index: ```python Path(__file__).resolve().parents[4] ``` This assumes that the Skill is always installed at one specific directory depth. There is no trusted configuration value, canonical allowed-root check, or validation that the resulting directory is the intended note vault. At the audited location: ```text /tmp/clawhub-codex-scan-v578qaprrnb6cdgd4hb7b7kgqs8eftnh-su1ZUq/artifact/scripts/capture_note.py ``` `parents[4]` resolves to the filesystem root, `/`. Consequently, the calculated destinations become `/Journal/...` and `/Inbox/...`, rather than directories inside the project or a clearly configured vault. The calls to `mkdir()` ...[truncated 1913 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/capture_note.py:24
Finding

Manual YAML Serialization Does Not Safely Encode User-Controlled Metadata

Content
View full analysis
str: lines: list[str] = ["---"] for key, value in data.items(): if value in ("", None, [], {}): continue if isinstance(value, list): lines.append(f"{key}:") for item in value: escaped_item = str(item).replace("\"", "\\\"") lines.append(f' - "{escaped_item}"') continue if isinstance(value, str): escaped = value.replace("\"", "\\\"") lines.append(f'{key}: "{escaped}"') continue lines.append(f"{key}: {value}") lines.append("---") lines.append("") return "\n".join(lines) ``` ### Technical Analysis The script constructs YAML frontmatter by concatenating strings and only escaping double-quote characters. This is not equivalent to valid YAML scalar serialization. User-controlled values can reach this function through note titles, tags, source URLs, and content-derived titles. Backslashes, control characters, Unicode escape-like sequences, and line breaks are not encoded according to YAML rules. For example, a backslash sequence supplied by a user may be interpreted by a YAML parser rather than preserved literally, while unsupported escape sequences or control characters may make the document invalid. The mismatch between the text supplied by the user and the value later interpreted by a YAML consumer can corrupt metadata or disrupt downstream note-indexing and automation systems. Although the dictionary keys are fixed by the script, the scalar values are not safely serialized. ### Attack Path 1. An attacker provides a crafted title, tag, or source URL containing YAML-significant backslash sequences, line breaks, or control characters. 2. The Agen ...[truncated 1218 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (7)

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger phrases are extremely broad, including everyday expressions like '记一下/存一下', which can cause accidental invocation during ordinary conversation. Because the skill's action is to write persistent data immediately, over-triggering can lead to unintended storage of private, irrelevant, or sensitive user content without clear consent.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill performs persistent note writes via a Python script but does not declare any explicit tool scope or permissions boundary. That creates a least-privilege and auditability gap: an agent may invoke file-writing behavior without a clearly advertised authorization model, increasing the chance of unintended or overbroad file modification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill directs the agent to write directly into the note system and even says to avoid asking questions first, but it gives no user-facing warning that this modifies persistent files. In context, this makes unintended file changes more likely because the agent is encouraged to act immediately on loosely phrased requests.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The default-behavior rules are ambiguous and aggressively route unclear requests into Inbox, where the skill is instructed to transform and '完善' content rather than preserve it verbatim. This increases the risk of misclassification, accidental persistence, and content distortion, especially when a user casually says '记一下' without intending durable note creation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The instruction “公式一律用 LaTeX 编写” imposes a mandatory formatting/language convention for formulas regardless of user preference. The file does not indicate that users can opt out or choose an alternative representation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The function returns the Chinese default title "未命名记录", which hardcodes a specific language choice in user-facing content. This file also uses Chinese-facing output text elsewhere, indicating the skill imposes a locale rather than offering a user-selectable language option.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The inserted journal block uses the label "来源:" for source URLs, which enforces a specific language in generated content. The file does not expose any language selection or document that the skill is intentionally limited to a Chinese-language environment.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.