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

Content
View full analysis

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
View 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

Content
View full analysis

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
View 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
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
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.

Content

Scanner excerpt · SKILL.md (reported line 13)May include surrounding context.

md
## 使用前提

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

## API接口

External Transmission

Medium
Category
Data Exfiltration
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.

Content

Scanner excerpt · SKILL.md (reported line 133)May include surrounding context.

md
"tags": ['"$tags"']
    }'
    
    curl -s -X POST http://192.168.18.15:5000/api/note \
        -H "Content-Type: application/json" \
        -d "$json_data"
}

Intent-Code Divergence

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
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.

Content

Scanner excerpt · __init__.py (reported line 47)May include surrounding context.

python
if folder:
                data["folder"] = folder
            
            response = requests.post(f"{self.base_url}/note", 
                                   json=data, 
                                   headers={"Content-Type": "application/json"})
            response.raise_for_status()

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
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.

Content

Scanner excerpt · __init__.py (reported line 59)May include surrounding context.

python
"""语义搜索笔记"""
        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()

Intent-Code Divergence

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · test_obsidian_kb.py (reported line 22)May include surrounding context.

python
cmd.append(url)
    
    result = subprocess.run(cmd, capture_output=True, text=True)
    return result.returncode, result.stdout, result.stderr

def test_health():

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · test_skill.py (reported line 26)May include surrounding context.

python
cmd.append(url)
    
    result = subprocess.run(cmd, capture_output=True, text=True)
    return result.returncode, result.stdout, result.stderr

def test_health():

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.