Back to skill

Security audit

Obsidian知识库集成

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but it gives agents broad shared knowledge-base read/write/index access over unauthenticated plaintext HTTP without enough scoping or user control.

Install only for an environment that intentionally trusts the 192.168.18.15 knowledge-base service and all agents that can access it. Do not store secrets, credentials, regulated data, private prompts, or sensitive project material unless the service is protected with authentication, TLS, access controls, and clear retention rules. Treat test scripts as live-write tests unless modified to use a staging endpoint or dry-run mode.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:25
Finding
Unauthenticated Knowledge-Base Operations over Plaintext HTTP## Vulnerability Details **File Location**: `SKILL.md:25-58` **Additional Affected Locations**: `obsidian_kb.py:17-109`, `__init__.py:14-100`, `obsidian_tools.sh:6-104` **Vulnerability Type**: Plaintext transmission and missing client authentication **Risk Level**: High The documented API operations use plaintext HTTP and provide no authentication token, API key, client certificate, or authorization header. ```bash curl -s -X POST http://192.168.18.15:5000/api/note \ -H "Content-Type: application/json" \ -d '{ "title": "笔记标题", "content": "# 内容\n\n正文...", "tags": ["标签1", "标签2"] }' ``` ```bash curl -s -X POST http://192.168.18.15:5000/api/search \ -H "Content-Type: application/json" \ -d '{"query": "搜索内容"}' ``` ```bash curl -s "http://192.168.18.15:5000/api/note?file=笔记文件名.md" curl -s http://192.168.18.15:5000/api/notes curl -s http://192.168.18.15:5000/api/stats curl -s -X POST http://192.168.18.15:5000/api/build ``` The Python implementations exhibit the same behavior. For example: ```python def __init__(self, api_url="http://192.168.18.15:5000"): self.api_url = api_url self.base_url = f"{api_url}/api" ``` ```python response = requests.post(f"{self.base_url}/note", json=data, headers={"Content-Type": "application/json"}) ``` ### Technical Analysis Plaintext HTTP provides neither confidentiality nor server authenticity. An attacker with access to the relevant network path can inspect note contents, filenames, search terms, and operational metadata. A network-positioned attacker may also modify API responses or submitted notes. The client sends no credentials or authorization information. The project documentation also describes the knowledge base as shared across agents without cross-host query restrictions. Consequently, any party able to reach the API may be able to invoke the same read, write, ...[truncated 2050 chars]
Remediation
## Remediation Suggestions 1. Replace plaintext HTTP with HTTPS and enforce certificate verification in all Python, shell, and documentation examples. 2. Require authenticated access using short-lived tokens, mutual TLS, or another centrally managed mechanism. 3. Apply per-agent authorization and separate read, write, listing, and index-administration permissions. 4. Restrict the service through host firewalls, network segmentation, and an authenticated reverse proxy. Do not treat private IP addressing as an access-control mechanism. 5. Bind the API only to required interfaces and explicitly allowlist authorized clients. 6. Protect sensitive notes with additional storage-level access controls and audit all reads, writes, and index-management actions. 7. Validate and sanitize note titles, folder names, filenames, and content on the server. 8. Make the API endpoint configurable rather than hard-coded, while rejecting non-HTTPS production endpoints. 9. Rotate any credentials introduced during remediation and monitor for prior unauthorized knowledge-base changes.

T09 · Insecure Skill Coding Practices

Warning
Location
obsidian_tools.sh:146
Finding
Predictable Temporary File Permits Symlink-Based File Overwrite## Vulnerability Details **File Location**: `obsidian_tools.sh:146-158` **Vulnerability Type**: Insecure temporary-file creation **Risk Level**: Medium ```bash # 临时文件 local temp_file="/tmp/script_note_$(date +%s).md" echo "$full_content" > "$temp_file" log_info "笔记内容已保存到临时文件: $temp_file" log_warning "由于系统没有curl,无法自动创建到Obsidian库" log_info "您可以手动将文件移动到: /mnt/share2win/openclaw_datas/obsidian_db/project_${project_name}/scripts/" echo "文件内容:" echo "$full_content" # 清理临时文件 rm -f "$temp_file" ``` ### Technical Analysis The temporary filename is derived solely from the current Unix timestamp in seconds. A local attacker can predict the exact filename or prepare candidate filenames for adjacent seconds. Shell output redirection opens an existing path without requiring exclusive creation and follows symbolic links. If an attacker creates the predicted path as a symbolic link before this script writes to it, the invoking user's shell will follow that link and truncate or overwrite the target file with the generated note content. The file mode is also controlled by the process umask. Under a permissive umask, temporary note contents may be readable by other local users before deletion. The script does not use `mktemp`, set a restrictive umask, verify file ownership or type, or register a cleanup trap. ### Attack Path 1. A local attacker determines that another user is about to invoke the `note` or `log` command. 2. The attacker calculates the current timestamp and creates `/tmp/script_note_<timestamp>.md` as a symbolic link to a file writable by the victim. 3. The victim invokes the script during that second. 4. The command `echo "$full_content" > "$temp_file"` follows the attacker's symbolic link. 5. The linked target is truncated and replaced with the generated note content under the victim's privileges. 6. If the script is run by a privileged account and the attacker selects a security-sensitive writa ...[truncated 980 chars]
Remediation
## Remediation Suggestions 1. Create temporary files atomically with `mktemp`: ```bash umask 077 temp_file=$(mktemp /tmp/script_note.XXXXXX.md) || return 1 ``` 2. Register cleanup immediately so interruption does not leave sensitive material behind: ```bash trap 'rm -f -- "$temp_file"' RETURN INT TERM HUP ``` 3. Keep a restrictive `umask 077` while handling note contents. 4. Never execute this helper with `sudo` or another elevated account. 5. Avoid writing a temporary file entirely if the content is only displayed and immediately deleted. 6. If a file must be retained, place it in a private user-owned directory with mode `0700`, create the file with mode `0600`, and verify its ownership and type before use. 7. Quote paths consistently and use `--` when deleting files to prevent option interpretation.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (37)

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The guide encourages creating notes and sharing/using a knowledge base but omits any warning that user-provided content may be persisted, indexed, and potentially visible to others. In a shared knowledge-management context, this can lead to accidental storage of sensitive data, confidential prompts, credentials, or personal information without informed user consent.

Natural-Language Policy Violations

Medium
Confidence
81% confidence
Finding
Mandating Chinese titles and identity-bearing YAML metadata without user choice creates unnecessary collection and standardization of identifying information. This increases privacy risk and may pressure users into disclosing identity attributes or using a locale-specific format that is not required for functionality.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The README prominently advertises creating notes and automatic indexing, but it does not clearly warn that these actions persistently modify a real knowledge base on a reachable internal service and filesystem-backed store. In an agent-skill context, unclear documentation around write operations can lead to unintended data creation, pollution of shared knowledge stores, and accidental disclosure or retention of sensitive content.

Natural-Language Policy Violations

Medium
Confidence
84% confidence
Finding
The skill documentation and conventions are entirely presented in Chinese, and line L108 explicitly mandates Chinese note titles. This imposes a language constraint without offering user opt-in, alternatives, or a documented region-specific justification, which matches the language/locale policy violation category.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill encourages storing notes in a fully shared knowledge base and performing networked note creation/search without any privacy warning or data-handling constraints. In practice, an agent could upload sensitive prompts, credentials, internal project details, or personal data to a shared service on the local network, causing unintended disclosure and persistence.

External Transmission

Medium
Category
Data Exfiltration
Content
## 使用前提

1. 确认API服务运行中:`curl -s http://192.168.18.15:5000/health`
2. 如果服务未启动,需要韩老板手动启动(需要sudo)

## API接口
Confidence
93% confidence
Finding
The skill directs agents to send requests to an unauthenticated HTTP service at a specific internal IP, including note contents and search queries. Because the knowledge base is explicitly shared across agents and hosts, any sensitive information sent there may be exposed to other consumers, intercepted on the network, or stored without access controls.

External Transmission

Medium
Category
Data Exfiltration
Content
"tags": ['"$tags"']
    }'
    
    curl -s -X POST http://192.168.18.15:5000/api/note \
        -H "Content-Type: application/json" \
        -d "$json_data"
}
Confidence
94% confidence
Finding
The helper function constructs JSON by directly interpolating shell variables into a `curl` POST body, then transmits the result to the remote note API over HTTP. Unescaped content can corrupt the JSON payload or enable injection of unintended fields, while the remote transmission itself can leak sensitive data into a shared store or across the network.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
`create_obsidian_note` is defined to take arguments in the order `(title, content, folder, tags)` at L120-L124, but the usage example at L222 passes five arguments in an order that places `"项目规划"` into `content`, the markdown body into `folder`, and `"项目"` into `tags`. This is not merely incomplete documentation; it actively describes a call pattern that does not match the code's behavior and would create an unintended request payload.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
`create_script_note` is defined with only `project_name`, `note_title`, and `content` at L154-L157, and its JSON body always derives tags internally as `["编剧", "$project_name"]` at L175-L180. However, `save_idea` and `record_problem` call it with additional trailing arguments at L248-L256 and L267-L277, implying those values affect note classification when the code actually discards them.

External Transmission

Medium
Category
Data Exfiltration
Content
if folder:
                data["folder"] = folder
            
            response = requests.post(f"{self.base_url}/note", 
                                   json=data, 
                                   headers={"Content-Type": "application/json"})
            response.raise_for_status()
Confidence
95% confidence
Finding
The create_note method sends arbitrary note content to a hard-coded HTTP endpoint on a private IP address, with no authentication, no TLS, and no validation of the destination. This can expose sensitive data in transit, enable interception or tampering on the local network, and route potentially confidential notes to an unintended service.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This code sends user-supplied note content, search queries, and file identifiers over HTTP requests to an external API, but there is no visible confirmation prompt, user-facing log, or warning in the code about that data transmission. Because these operations can expose potentially sensitive knowledge-base contents, the lack of disclosure matches the missing-warning criterion for code files.

External Transmission

Medium
Category
Data Exfiltration
Content
"""语义搜索笔记"""
        try:
            data = {"query": query, "limit": limit}
            response = requests.post(f"{self.base_url}/search", 
                                   json=data, 
                                   headers={"Content-Type": "application/json"})
            response.raise_for_status()
Confidence
95% confidence
Finding
The search_notes method transmits user queries to the same hard-coded HTTP service without transport security or authentication. Search queries can themselves contain sensitive operational, personal, or proprietary information, and plaintext transmission makes them vulnerable to monitoring, interception, or manipulation.

Intent-Code Divergence

Medium
Confidence
90% confidence
Finding
The save_experience method silently injects fixed host and agent identity metadata into every note, which can misattribute content and leak internal infrastructure details to the remote knowledge base. Because this metadata is unrelated to caller input and is automatically transmitted, it creates an integrity and privacy risk, especially if notes are shared, synced, or exposed outside the local environment.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The client is hardcoded to send note content, search queries, and metadata to a remote HTTP API on a private IP address, but the tool does not clearly warn users that their data leaves the local process. Because the transport uses plain HTTP rather than HTTPS, note data may also be exposed to interception or tampering on the network, increasing the privacy and integrity risk.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The create_note functionality performs a remote write operation that can modify user knowledge-base data, but the CLI does not provide a clear warning or confirmation that it will create content through a network API. In this context, unintended or misunderstood execution could alter user data on the remote Obsidian service without informed consent.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
All user-facing comments, logs, errors, and help text are presented in Chinese, and the script labels itself as dedicated to a specific user role without any opt-in or language choice. Under the locale policy, forcing a specific language can be a natural-language policy violation unless the restriction is explicitly justified or the user is given a choice.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The search function places user-provided query text directly into a GET URL sent to a remote internal API, with no privacy notice and no URL encoding. This can expose potentially sensitive user queries in network logs, shell history, proxies, or server access logs, and malformed characters in the query may alter request semantics.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The comment and function naming indicate note creation capability, and the CLI help likewise advertises '创建编剧笔记'. In reality, the implementation explicitly states it cannot create the note automatically, saves to a temporary file, displays manual instructions, and then removes the file, so no note is persisted in the Obsidian repository.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The script's comments and printed status messages are written in Chinese throughout, with no option for users to select another language or indication that the skill is intentionally region-specific. This creates a natural-language policy concern because the skill imposes a locale choice by default.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The module and function documentation describe this file as a test script for an Obsidian knowledge-base skill, but its implementation depends on spawning the `curl` executable via `subprocess.run` rather than using in-process HTTP logic. Launching subprocesses is a broader capability than ordinary API testing requires and is not justified by the stated testing purpose in the file documentation.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
cmd.append(url)
    
    result = subprocess.run(cmd, capture_output=True, text=True)
    return result.returncode, result.stdout, result.stderr

def test_health():
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
cmd.append(url)
    
    result = subprocess.run(cmd, capture_output=True, text=True)
    return result.returncode, result.stdout, result.stderr

def test_health():
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script performs a state-changing POST request that creates a remote note but does not provide an explicit warning, confirmation step, or safe default to prevent accidental modification of the knowledge base. In a testing context, silently writing data to a live service can cause unauthorized content creation, data pollution, and unintended side effects, especially because the target is a fixed non-local IP that may be a shared environment.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The test routine performs a real write operation against a hard-coded remote knowledge-base API and creates a note without any confirmation, dry-run mode, or prominent warning about side effects. In an agent-skill context, this is dangerous because simply 'testing' the skill alters external state and may pollute or tamper with a shared datastore unexpectedly.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This code file contains natural-language documentation and printed output entirely in Chinese, presenting the skill usage in a single forced language. The policy explicitly calls for flagging language or locale constraints when no user opt-in or justified region-specific scope is provided.

Static analysis

No suspicious patterns detected.