Back to skill

Security audit

Claude-Obsidian 知识引擎

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent Obsidian knowledge-base skill, but it can make broad persistent changes to a vault and includes an unsafe generated shell-script workflow.

Install only if you want an agent to actively maintain and modify an Obsidian-style vault. Use dry-run or previews where possible, keep backups before batch organization, avoid executing the generated .claude_fix_suggestions.sh file unless you inspect it carefully, and do not process confidential notes through any API-based workflow without confirming where the content is sent.

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/auto_link.py:117
Finding
Shell Command Injection Through Generated Repair Script## Vulnerability Details **File Location**: `scripts/auto_link.py`, lines 13–15 and 117–123 **Vulnerability Type**: Shell command injection through unsafe script generation **Risk Level**: Medium The application inserts untrusted Markdown link content directly into a generated Bash script without rejecting line breaks or other control characters. **Source of untrusted content (`scripts/auto_link.py`, lines 13–15):** ```python def extract_links(content): """提取 [[双向链接]] 中的笔记名""" return re.findall(r'\[\[([^\]]+)\]\]', content) ``` **Vulnerable script-generation operation (`scripts/auto_link.py`, lines 117–123):** ```python # 生成修复建议(dry_run=false 时输出可执行脚本) if not dry_run and (dead_links or orphans): fix_script = vault / ".claude_fix_suggestions.sh" with open(fix_script, 'w', encoding='utf-8') as f: f.write("#!/bin/bash\n# Claude-Obsidian 修复建议(手动确认后执行)\n\n") for dl in dead_links: f.write(f"# 在 {dl['file'].relative_to(vault)} 中将 [[{dl['link']}]] 替换为 [[{dl['suggestion']}]]\n") ``` ### Technical Analysis `extract_links()` obtains link text directly from Markdown files inside the user-selected vault. Its regular expression uses the character class `[^\]]+`, which excludes closing square brackets but does not exclude newline or carriage-return characters. The extracted value is subsequently stored in `dl['link']` and interpolated into `.claude_fix_suggestions.sh`. Although the generated content is intended to be a shell comment, an embedded newline can terminate the comment. The next line is then interpreted as a shell command if the generated file is executed. The derived `dl['suggestion']` value is also unsafe because operations such as `strip()`, `replace()`, and `lower()` do not remove embedded line breaks. ### Attack Path 1. An attacker supplies, shares, or causes the user to import a Markdown file into the scanned vault. 2. The Markdown file contains a crafte ...[truncated 1404 chars]
Remediation
## Remediation Suggestions 1. **Do not generate executable shell files from vault content.** Generate a non-executable Markdown, JSON, or plain-text report instead. This is the preferred remediation because the file currently contains only comments and does not require shell semantics. 2. **Reject control characters in all untrusted fields.** Validate extracted links and relative paths before using them in generated output: ```python def validate_single_line(value): if any(ch in value for ch in ("\n", "\r", "\x00")): raise ValueError("Link contains prohibited control characters") return value ``` 3. **Make report-only behavior the default.** Require an explicit option to generate any executable artifact rather than generating `.claude_fix_suggestions.sh` whenever `--dry-run` is absent. 4. **Use structured repair data.** Store the source file, original link, and suggested replacement as JSON fields. A separate trusted tool can consume that data without invoking a shell. 5. **If shell generation is unavoidable, avoid embedding data in comments or command text.** Pass validated values as arguments to a fixed program and quote each value with a proven shell-escaping function such as `shlex.quote()`. Shell quoting alone should supplement, not replace, rejection of newline and control characters. 6. **Apply safe file permissions.** Create generated reports without executable permission and avoid a `.sh` extension unless executable behavior is genuinely required. 7. **Add regression tests** covering links with newline characters, carriage returns, shell metacharacters, command substitutions, backticks, quotes, and crafted filenames. Verify that these inputs are rejected or represented only in a non-executable structured format.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (10)

Missing User Warnings

High
Confidence
97% confidence
Finding
The entity-extraction script states that it uses AI via an API on markdown input, but it does not warn that note contents may be transmitted to an external service. In a PKM/Obsidian vault, notes often contain highly sensitive personal, medical, financial, research, or business information, so silent external transmission creates a significant confidentiality and compliance risk.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill clearly describes reading and writing user files in the vault, yet it declares no explicit tool scope or permission boundary. That creates an authorization ambiguity where a host system or user may not receive a clear signal that the skill can modify local knowledge-base contents, increasing the chance of unintended file access or writes.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The activation terms are extremely broad and include common productivity and note-taking language, so the skill may trigger during ordinary conversations that are not intended to invoke persistent knowledge-base automation. In this skill's context, accidental activation is more dangerous because the workflow includes scanning, linking, and writing to a vault rather than only generating text.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill states that every conversation is a write operation and repeatedly instructs the agent to create, update, and reorganize notes, but it does not provide a clear user-facing warning or transactional confirmation model. This is dangerous because a mistaken activation, misunderstanding, or prompt injection through user-provided content could lead to silent, large-scale modification of the user's knowledge base.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The document instructs users to persist operational state and user preferences in `.cache/hot_cache.json` across sessions, but it does not disclose retention behavior, local data modification, or the sensitivity of stored metadata. In a personal knowledge-base context, cached topics, processed files, and preferences can reveal private interests and activity history, increasing privacy and forensic exposure if the device or vault is shared or compromised.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The clear command replaces the cache file contents with an empty object, which irreversibly deletes the previously stored session state. Although the command name suggests clearing, the file contains no confirmation prompt, cautionary comment/docstring, or user-facing warning beyond the success message after deletion.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
This file is a markdown template library and all visible instructional text and field examples are in Chinese. Under the policy rule for natural-language violations, forcing a specific language without user opt-in can be a locale-policy issue when no alternative or justification is provided.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
A language or locale policy issue applies across all file types when a skill effectively forces a specific language without user opt-in. This file presents all operational instructions in Chinese and does not indicate any optional language support or justified locale restriction, which may conflict with organizational expectations for language choice.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
This code file contains user-facing natural-language documentation only in Chinese, which effectively imposes a specific language/locale without offering a choice or documenting a justified locale constraint. Under the policy, language restrictions should be opt-in or clearly justified as region-specific.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The script's docstrings, help text, and runtime messages are consistently presented in Chinese, with no option for the user to select another language or locale. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Static analysis

No suspicious patterns detected.