Back to skill

Security audit

Flatnotes 笔记服务

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Flatnotes integration, but it handles reusable credentials and note data without enforcing a trusted HTTPS destination, so it needs review before use.

Install only if you trust the Flatnotes host you configure. Use an HTTPS URL, avoid passing passwords on the command line, prefer a revocable token or secret manager over storing a password in shell startup files, and require explicit confirmation before update or delete operations.

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
scripts/get_token.py:34
Finding

Credentials and sensitive note data can be transmitted to an unrestricted or plaintext destination

Content
View full analysis
str: """使用用户名密码获取访问令牌""" if base_url is None: base_url = get_base_url() if username is None: username = os.getenv("FLATNOTES_USERNAME") if password is None: password = os.getenv("FLATNOTES_PASSWORD") if not username or not password: print("❌ 错误: FLATNOTES_USERNAME 或 FLATNOTES_PASSWORD 环境变量未设置") print() print("📌 请先配置以下环境变量:") print(" export FLATNOTES_BASE_URL=\"https://your-flatnotes-host\"") print(" export FLATNOTES_USERNAME=\"your-username\"") print(" export FLATNOTES_PASSWORD=\"your-password\"") print() print(" 添加到 ~/.bashrc 后执行: source ~/.bashrc") print(" 或通过 --username 和 --password 参数传入") sys.exit(1) url = f"{base_url}/api/token" data = json.dumps({"username": username, "password": password}).encode("utf-8") req = urllib.request.Request( url, data=data, headers={ "Content-Type": "application/json", "Content-Length": len(data) }, method="POST" ) try: with urllib.request.urlopen(req) as response: ``` `scripts/create_note.py:34-55`: ```python def get_token_from_credentials(base_url: str) -> str: """使用环境变量中的用户名密码获取令牌""" username = os.getenv("FLATNOTES_USERNAME") password = os.getenv("FLATNOTES_PASSWORD") if not username or not password: print("❌ 错误: 请设置 FLATNOTES_USERNAME 和 FLATNOTES_PASSWORD 环境变量") sys.exit(1) url = f"{base_url}/api/ ...[truncated 4260 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/get_token.py:81
Finding

Password accepted through a command-line argument can leak through process metadata and shell history

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (19)

Tainted flow: 'req' from os.getenv (line 76, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/create_note.py (reported line 55)May include surrounding context.

python
)
    
    try:
        with urllib.request.urlopen(req) as response:
            result = json.loads(response.read().decode("utf-8"))
            return result.get("access_token") or result.get("token")
    except Exception:

Tainted flow: 'req' from os.getenv (line 76, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/create_note.py (reported line 79)May include surrounding context.

python
)
    
    try:
        with urllib.request.urlopen(req) as response:
            result = json.loads(response.read().decode("utf-8"))
            return result.get("access_token") or result.get("token")
    except Exception:

Tainted flow: 'req' from os.getenv (line 71, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/get_note.py (reported line 55)May include surrounding context.

python
)
    
    try:
        with urllib.request.urlopen(req) as response:
            result = json.loads(response.read().decode("utf-8"))
            return result.get("access_token") or result.get("token")
    except Exception:

Tainted flow: 'req' from os.getenv (line 71, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/get_note.py (reported line 76)May include surrounding context.

python
)
    
    try:
        with urllib.request.urlopen(req) as response:
            result = json.loads(response.read().decode("utf-8"))
            return result.get("access_token") or result.get("token")
    except Exception:

Tainted flow: 'req' from os.getenv (line 55, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/get_token.py (reported line 66)May include surrounding context.

python
)
    
    try:
        with urllib.request.urlopen(req) as response:
            result = json.loads(response.read().decode("utf-8"))
            token = result.get("access_token") or result.get("token")
            if token:

Tainted flow: 'req' from os.getenv (line 75, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/search_notes.py (reported line 55)May include surrounding context.

python
)
    
    try:
        with urllib.request.urlopen(req) as response:
            result = json.loads(response.read().decode("utf-8"))
            return result.get("access_token") or result.get("token")
    except Exception:

Tainted flow: 'req' from os.getenv (line 75, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/search_notes.py (reported line 80)May include surrounding context.

python
)
    
    try:
        with urllib.request.urlopen(req) as response:
            result = json.loads(response.read().decode("utf-8"))
            return result.get("access_token") or result.get("token")
    except Exception:

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

The documented DELETE endpoint enables irreversible note deletion by title, and in an agent-skill context this creates meaningful tool-parameter abuse risk if user input is passed through without confirmation or validation. The danger is amplified by the skill metadata stating it can delete notes: a prompt-injected or mistaken action could destroy user data with a single call.

Content

Scanner excerpt · references/api_docs.md (reported line 71)May include surrounding context.

6. 删除笔记

text
DELETE /api/notes/{title}

7. 搜索笔记

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill performs sensitive actions using environment variables and network access, but it does not declare an explicit tool scope such as permissions or allowed-tools. This weakens policy enforcement and increases the chance an agent executes networked note operations or uses stored credentials without clear runtime constraints, especially since the skill handles a sensitive password and can create, modify, and delete remote content.

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 66)May include surrounding context.

直接 API 调用:

bash
curl -X POST $FLATNOTES_BASE_URL/api/notes \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{"title": "标题", "content": "# Markdown 内容"}'

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 94)May include surrounding context.

更新笔记

bash
curl -X PATCH $FLATNOTES_BASE_URL/api/notes/原标题 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{"newTitle": "新标题", "newContent": "新内容"}'

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This markdown file documents creating, updating, and deleting notes, which can affect user data, but it does not include any warning about data modification or deletion consequences. Under the markdown-specific criteria for missing user warnings, descriptions of behaviors that could affect user data should disclose that impact.

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 · references/api_docs.md (reported line 166)May include surrounding context.

使用示例

创建笔记

curl 示例:

bash
curl -X POST https://your-flatnotes-host/api/notes \
  -H "Content-Type: application/json" \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script will send username/password and note content to whatever URL is in FLATNOTES_BASE_URL, but it does not enforce HTTPS or clearly warn users about disclosure risk. If the base URL is configured as plain HTTP or pointed at an untrusted host, credentials and note data could be intercepted or sent to an attacker-controlled service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The module docstring, usage instructions, environment-variable guidance, and user-facing messages are written only in Chinese. Under the policy, a skill should not impose a specific language or locale unless it offers opt-in choice or clearly documents a justified regional constraint, which this file does not.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This code file contains natural-language documentation and runtime messages entirely in Chinese, including the module docstring and CLI help text. The policy for SQP-3 flags language/locale constraints when a skill forces a specific language without offering the user a choice or documenting a justified locale-specific scope.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
72% confidence
Finding

The markdown describes uploading files to the service, which can affect user data and privacy, but provides no warning about sending file contents to the server. For markdown files, behaviors that may affect user data or privacy should include a clear disclosure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

All docstrings, help text, and runtime messages are in Chinese, with no indication that the language is optional or that the tool is intended only for a Chinese-speaking environment. This can violate language/locale policy when skills impose a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code includes its docstring and all user-facing CLI output in Chinese, which imposes a specific language on users. The file does not provide any opt-in, alternative locale, or documentation indicating that the skill is intentionally limited to Chinese-speaking users.

Content

No source excerpt is available for this finding.