Back to skill

Security audit

Siyuan Note

Security checks for vulnerabilities and agentic risk

Overview

This SiYuan note skill is not clearly malicious, but it gives an agent broad authenticated access to private local notes and exposes risky operations without enough scoping or warnings.

Review before installing. Use it only if you trust the agent with your SiYuan API token and private notes. Avoid broad or ambiguous prompts, confirm any write/delete/export/SQL action, do not send note contents through the documented proxy endpoint unless you explicitly intend external network access, and prefer running the helper in an isolated Python environment with reviewed dependencies.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/siyuan.py:58
Finding
SQL Injection in Search and Notebook Filtering Commands## Vulnerability Details **File Location**: `scripts/siyuan.py`, lines 58-79 **Vulnerability Type**: SQL injection through unescaped CLI-controlled values **Risk Level**: Medium ### Vulnerable Code ```python def search(keyword, limit=20): results = post("/api/query/sql", { "stmt": f"SELECT id, hpath, content FROM blocks WHERE content LIKE '%{keyword}%' LIMIT {limit}" }) print(json.dumps(results, indent=2, ensure_ascii=False)) return results def search_titles(keyword, limit=20): results = post("/api/query/sql", { "stmt": f"SELECT id, hpath, title FROM blocks WHERE type = 'd' AND title LIKE '%{keyword}%' LIMIT {limit}" }) print(json.dumps(results, indent=2, ensure_ascii=False)) return results def list_docs(notebook): results = post("/api/query/sql", { "stmt": f"SELECT id, title, hpath FROM blocks WHERE notebook = '{notebook}' AND type = 'd'" }) print(json.dumps(results, indent=2, ensure_ascii=False)) return results ``` ### Technical Analysis The `keyword` and `notebook` values originate from command-line arguments and are inserted directly into SQL string literals through Python f-strings. The implementation performs no parameter binding, escaping, format validation, or rejection of SQL control characters. Although the Skill intentionally offers a separate raw `sql` command, these three commands are presented as constrained search and listing operations. Injection allows an argument supplied to a constrained command to change the structure and semantics of the generated SQL statement. For example, a crafted keyword containing a quote, a condition such as `OR 1=1`, a SQL comment marker, and a newline can terminate the intended `LIKE` expression and neutralize the remaining query text. A compatible `UNION SELECT` expression could potentially retrieve fields outside the columns ordinarily exposed by a given command. ### Attack P ...[truncated 1319 chars]
Remediation
## Remediation Suggestions 1. Use parameterized SQL statements if the SiYuan API supports query parameters. 2. If binding is unavailable, avoid dynamically generated SQL and use a dedicated SiYuan search endpoint where possible. 3. Otherwise, escape SQL string literals using a well-tested implementation rather than ad hoc replacement. 4. Validate notebook identifiers against SiYuan's documented identifier format and reject all nonconforming values. 5. Validate `limit` as an integer and enforce a conservative range before incorporating it into a query. 6. Reject unexpected control characters, statement delimiters, and comment syntax as defense in depth. 7. Keep intentionally unrestricted SQL execution isolated in the explicitly named `sql` command and require clear user confirmation before running statements that can expose broad note data. 8. Add tests using quotes, comment markers, newlines, Boolean conditions, and `UNION` expressions to verify that user input cannot alter query structure.

T08 · Insecure Dependencies

Note
Location
scripts/siyuan.py:19
Finding
Unpinned Third-Party Dependency Installation## Vulnerability Details **File Location**: `scripts/siyuan.py`, lines 19-24 **Vulnerability Type**: Unpinned dependency retrieved from a mutable package source **Risk Level**: Low ### Vulnerable Code ```python try: import requests except ImportError: print("Dependency required: pip install requests") sys.exit(1) ``` The source message instructs the user to run `pip install requests` without specifying a reviewed version, package hash, lockfile, trusted index, or isolated environment. ### Technical Analysis `requests` is a legitimate and correctly spelled package; there is no evidence that this project deliberately references a malicious or typosquatted dependency. The risk arises because the installation instruction leaves resolution entirely to the user's current pip configuration and mutable package indexes. The installed artifact may vary over time and across environments. A compromised package release, package index, configured mirror, or dependency-resolution path could therefore introduce code that was not part of this audit. Python package code can execute during installation and later when imported by the Skill. ### Attack Path 1. The user runs the script in an environment where `requests` is unavailable. 2. The script displays an instruction to install the unpinned package. 3. The user runs `pip install requests`. 4. Pip resolves the package and transitive dependencies using the environment's configured index or mirror without hash verification. 5. If that supply chain is compromised, malicious package code may execute during installation or when `requests` is imported. 6. Such code would run with the privileges of the Python or pip process. ### Impact Assessment In a successful supply-chain compromise, attacker-controlled code could obtain the permissions of the account performing installation or running the Skill. This could include access to files, environment variables such as `S ...[truncated 264 chars]
Remediation
## Remediation Suggestions 1. Declare dependencies in a committed requirements or lock file using a reviewed version or narrowly controlled version range. 2. Record and verify artifact hashes, and install with `pip --require-hashes` where practical. 3. Document the trusted package index and avoid relying on unreviewed environment-specific mirrors. 4. Recommend installation in a dedicated virtual environment rather than a global or privileged Python environment. 5. Add automated dependency vulnerability and integrity scanning to the release process. 6. Review and update the pinned dependency deliberately instead of allowing silent resolution to newly published versions.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (12)

Description-Behavior Mismatch

High
Confidence
95% confidence
Finding
The reference documents a general forward-proxy endpoint that can reach arbitrary external URLs, which materially expands the skill from local note operations into outbound networking. In an agent context, this can enable data exfiltration, unapproved internet access, or misuse of local note content in external requests, especially because the skill description frames it as a local assistant rather than a network-capable one.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
A forward-proxy endpoint is context-inappropriate for a local SiYuan note assistant because it allows arbitrary outbound requests unrelated to note management. In practice, this creates a direct path for exfiltration, SSRF-like abuse via the local app as a broker, and policy bypass if the agent is otherwise expected to remain local-only.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill exposes capabilities to access environment-derived secrets and make network requests, yet it declares no explicit tool scope or permission boundaries. That omission can let the agent invoke sensitive operations more broadly than users or the platform may expect, especially when the skill also handles a local API token and write-capable endpoints.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The trigger phrases include broad everyday requests like creating documents, searching notes, and querying databases, which can cause the skill to activate unintentionally. Because this skill can query and modify local notes through authenticated local APIs, accidental invocation increases the chance of unintended data access or writes.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill description and instructions do not warn users that it can read, search, and modify potentially sensitive local notebook data using an authenticated local API. Without a clear risk notice, users may not understand that ordinary requests could expose private notes or cause persistent changes to their local knowledge base.

External Transmission

Medium
Category
Data Exfiltration
Content
### 列出所有笔记本
```bash
curl -X POST http://127.0.0.1:6806/api/notebook/lsNotebooks \
  -H "Authorization: Token <TOKEN>"
```
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
This markdown file describes deletion endpoints such as deleting notebooks, documents, blocks, and files, but does not include any warning that these actions can remove user data. Under the markdown-specific missing-warning rule, documentation should disclose behaviors that could affect user data or system integrity.

Description-Behavior Mismatch

Medium
Confidence
83% confidence
Finding
These file-management APIs operate on general workspace paths and go beyond ordinary note editing into lower-level file creation, overwrite, rename, listing, and deletion. In an agent skill, that broader filesystem-like surface increases the chance of unintended destructive actions or access to files outside the user's expected note-editing scope.

Description-Behavior Mismatch

Medium
Confidence
79% confidence
Finding
Export and Pandoc conversion extend the skill beyond simple local note CRUD into bulk data extraction and document transformation. That can facilitate mass export of note content or risky invocation patterns through conversion tooling, making the capability set broader and more dangerous than the manifest suggests.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The proxy endpoint is documented without any warning that outbound requests may send user note contents, metadata, or system-derived data to external services. In the context of an agent skill, omission of this warning materially increases the chance of inadvertent data egress because users may reasonably assume the assistant is local-only.

External Transmission

Medium
Category
Data Exfiltration
Content
def post(endpoint, data=None):
    r = requests.post(f"{BASE_URL}{endpoint}", json=data or {}, headers=headers(), timeout=10)
    r.raise_for_status()
    resp = r.json()
    if resp.get("code") != 0:
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Low
Confidence
77% confidence
Finding
The file instructs users to authenticate with an Authorization token, but provides no disclosure that the token is sensitive and should not be exposed, logged, or shared. For markdown documentation, omission of privacy or credential-safety warnings can qualify when the behavior involves sensitive access.

Static analysis

No suspicious patterns detected.