Back to skill

Security audit

Personal Wiki

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches a personal wiki workflow, but it asks for sensitive note credentials and has under-scoped credential persistence, dependency, and browser-viewer risks that users should review before installing.

Install only if you are comfortable granting access to your IMA, Evernote, and ~/wiki content. Avoid writing Evernote tokens to ~/.zshrc, use an isolated virtual environment instead of the documented global pip setup, and do not open generated wiki-graph HTML on sensitive imported content unless the viewer is fixed to sanitize markdown and avoid untrusted remote scripts.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/viz/viz.js:184
Finding

Stored Cross-Site Scripting in Generated Knowledge Graph

Content
View full analysis
window.BUNDLE_NAME = __BUNDLE_NAME__; window.BUNDLE = __BUNDLE_DATA__; ``` ```javascript const body = bundle.bodies[conceptId] || ""; const html = marked.parse(body, { breaks: false, gfm: true }); const bodyEl = document.getElementById("detail-body"); bodyEl.innerHTML = html; ``` ### Technical Analysis Wiki page bodies originate from local files, IMA notes, or Evernote notes and are treated as trusted HTML after Markdown conversion. `marked.parse()` does not provide HTML sanitization, and the resulting content is assigned directly to `innerHTML`. Consequently, HTML elements and event-handler attributes embedded in a wiki page can become executable DOM content. There is a second injection point in the graph generator. `json.dumps()` safely creates JSON syntax but does not escape an HTML closing script sequence such as ``. Because the serialized graph is inserted directly inside an executable `
Remediation
View remediation
... ``` Then parse its text content: ```javascript const bundle = JSON.parse( document.getElementById("bundle-data").textContent ); ``` 4. During JSON serialization, escape at least `<`, `>`, `&`, U+2028, and U+2029. Escaping `<` prevents `` from terminating the element. 5. Add a restrictive Content Security Policy that disallows inline scripts and limits network destinations. 6. Add regression tests containing script tags, SVG event handlers, image error handlers, and literal `` sequences. ]]>

T03 · Remote Payload Retrieval and Execution

Warning
Location
scripts/viz/viz.html:6
Finding

Remote JavaScript Is Retrieved and Executed Without Integrity Verification

Content
View full analysis
``` ### Technical Analysis The generated viewer is described as a single-file visualization whose data remains local, but it loads two executable JavaScript resources from jsDelivr whenever the HTML file is opened. Neither resource has a Subresource Integrity hash. Although package versions are present in the URLs, the browser still trusts the CDN response at runtime. A compromised CDN, package publication, DNS path, or delivery infrastructure could replace the expected libraries with attacker-controlled JavaScript after the Skill itself has been audited. Remote scripts execute in the same document context as the embedded graph data and therefore can directly access `window.BUNDLE`. ### Attack Path 1. The user generates `wiki-graph.html`. 2. The user opens the generated file while connected to the network. 3. The browser requests Cytoscape and Marked from jsDelivr. 4. If either delivered resource is compromised or substituted, attacker-controlled JavaScript executes in the viewer. 5. The script reads `window.BUNDLE`, including the full bodies of all included wiki pages. 6. The script sends the collected information to an attacker-controlled endpoint or alters the viewer output. ### Impact Assessment Exploitation permits arbitrary JavaScript execution in the knowledge graph viewer. The primary impact is disclosure of the complete bundled wiki, including potentially confidential personal or business information. The attacker could also manipulate the graph, present misleading content, or redirect the user to malicious resources. This does not directly grant native operatin ...[truncated 120 chars]
Remediation
View remediation
``` 3. Maintain a lockfile or equivalent manifest recording exact dependency versions and hashes. 4. Add a Content Security Policy restricting scripts to approved hashes or bundled content and limiting `connect-src`. 5. Document clearly that the current viewer requires network access and executes third-party code until the dependencies are vendored. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:156
Finding

Environment-Controlled Evernote Host Can Receive the Authentication Token

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:148
Finding

Unpinned Packages Are Installed Into System-Managed Python

Content
View full analysis
**重要**:evernote2 需要 `python3.12`(不兼容 Python 3.14+,因 `distutils` 已移除)。 > 所有印象笔记相关脚本必须用 `python3.12` 执行。 > 依赖已安装:`python3.12 -m pip install evernote2 oauth2 setuptools --break-system-packages` > evernote2 库需 patch:`/opt/homebrew/lib/python3.12/site-packages/evernote2/api/client.py` 第145行 `getargspec` → `getfullargspec`(已完成) ``` ### Technical Analysis The documented installation command does not pin versions or verify package hashes. It also uses `--break-system-packages`, which bypasses protections intended to keep package-manager-owned Python environments consistent. As a result, future executions can install different package contents than those originally reviewed. Package repository compromise, dependency compromise, or an unexpected package release could execute arbitrary installation-time or import-time Python code. Modifying a globally installed package in `/opt/homebrew/lib` also makes the behavior of other applications using that interpreter depend on this Skill's setup. ### Attack Path 1. A user or Agent follows the dependency setup instructions. 2. `pip` resolves current versions of `evernote2`, `oauth2`, `setuptools`, and transitive dependencies from the configured package index. 3. A compromised or unexpectedly changed package is downloaded. 4. Package installation or later import executes attacker-controlled Python code with the user's privileges. 5. Because the environment is system-managed and shared, the altered package may affect later Python processes beyond the Skill invocation. ### Impact Assessment A malicious package can execute code with the privileges of the user running `pip` or invoking the Skill. It could access the user's files, environment variables, IMA credentials, Evernote token, and wiki contents. ...[truncated 264 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:196
Finding

Evernote Token Is Persisted in Plaintext Shell Startup Configuration

Content
View full analysis
🔴 **安全**:token 若被贴进对话(HAI 环境会进内网日志),提醒用户下次直接在 Terminal `export` 或写 `~/.zshrc`。刷新后主动帮用户把新 token 覆盖进 `~/.zshrc`(Edit 替换旧行),省得每次过期重贴。 ``` ```bash # 用 Edit 工具替换 ~/.zshrc 里的旧 EVERNOTE_TOKEN 行,不要 append 造成重复 grep -n "EVERNOTE_TOKEN" ~/.zshrc # 先定位旧行 ``` ### Technical Analysis The Skill instructs the Agent to proactively write the Evernote developer token into `~/.zshrc`. Shell startup files are plaintext configuration files, are frequently copied into backups or dotfile repositories, and may be readable by local tools operating as the same user. Exporting the token from `.zshrc` also places it in the environment of every subsequently launched shell process and potentially many child applications, increasing the number of processes and diagnostic tools that can observe the secret. This is credential persistence rather than a backdoor installation, but it unnecessarily expands the token's exposure. ### Attack Path 1. The Evernote token expires and the user generates a replacement. 2. Following the Skill instructions, the Agent replaces or adds the token declaration in `~/.zshrc`. 3. The token remains stored in plaintext across sessions. 4. A malicious same-user process, exposed backup, shared dotfile repository, support bundle, or unintended file disclosure reads the startup file. 5. The attacker uses the token while it remains valid to access the associated Evernote account. ### Impact Assessment Exposure of the token can compromise the confidentiality and integrity of Evernote notes available to the credential. The attacker may be ...[truncated 239 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (13)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill defines procedures that read and modify local wiki files, but it does not declare an explicit tool scope such as permissions or allowed-tools. That omission weakens least-privilege controls and makes it harder for a runtime or reviewer to constrain file access to only the intended paths.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

步骤 1 — 拉取笔记列表

bash
curl -s --max-time 15 \
  -X POST "https://ima.qq.com/openapi/note/v1/list_note_by_folder_id" \
  -H "ima-openapi-clientid: $IMA_CLIENT_ID" \
  -H "ima-openapi-apikey: $IMA_API_KEY" \

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs persisting refreshed Evernote credentials into ~/.zshrc, which stores secrets in plaintext in a broadly sensitive shell startup file. This increases the chance of credential leakage through backups, accidental disclosure, overbroad file reads, or later commands that expose shell configuration contents.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The workflow recommends updating EVERNOTE_TOKEN in ~/.zshrc without a clear warning that this persists credentials in plaintext and modifies shell configuration. That combination can surprise users and lead to long-lived secret exposure well beyond the immediate wiki task.

Content

No source excerpt is available for this finding.

File System Enumeration

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Content

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

步骤 1 — 扫描新文件

bash
ls -la ~/wiki/raw/

对比 ~/wiki/log.md 中"本地文件"表格,找出未处理的文件。

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This is a true client-side XSS risk, not merely a missing warning. Untrusted markdown from the wiki body is rendered to HTML with marked.parse() and then assigned directly to innerHTML, with no sanitization step shown. In a personal wiki/ingest skill, content may come from imported notes or raw files, so an attacker could plant HTML/script-capable payloads that execute when a node is viewed in the visualization.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The manifest describes this skill as operating on a personal wiki and ingesting local files, but the implementation detail for PDFs requires spawning an external command via subprocess.run. Launching subprocesses is a stronger capability than the skill description suggests, and it is not explicitly justified in the manifest even though it is used for document extraction.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The markdown directs the skill to write or update multiple local files under ~/wiki during ingest. While this is part of the skill's function, the description does not provide an explicit user warning that running ingest will modify local knowledge-base files and logs.

Content

No source excerpt is available for this finding.

Scope Creep

Low
Category
Excessive Agency
Confidence
70% confidence
Finding

Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Content

Scanner excerpt · scripts/viz/OKF-LICENSE.md (reported line 28)May include surrounding context.

md
exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical

Scope Creep

Low
Category
Excessive Agency
Confidence
70% confidence
Finding

Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Content

Scanner excerpt · scripts/viz/OKF-LICENSE.md (reported line 33)May include surrounding context.

md
exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical

Scope Creep

Low
Category
Excessive Agency
Confidence
70% confidence
Finding

Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Content

Scanner excerpt · scripts/viz/OKF-LICENSE.md (reported line 56)May include surrounding context.

md
exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical

Scope Creep

Low
Category
Excessive Agency
Confidence
70% confidence
Finding

Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Content

Scanner excerpt · scripts/viz/OKF-LICENSE.md (reported line 161)May include surrounding context.

md
exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

This HTML file pulls JavaScript from third-party CDNs, which causes network requests to external services when the page is opened. There is no visible notice in the file informing users that opening the viewer will contact external hosts.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.