Back to skill

Security audit

微信收藏知识库

Security checks for vulnerabilities and agentic risk

Overview

This skill is mostly a disclosed WeChat favorites organizer, but it also ships a broad database decryption script that can turn unrelated encrypted WeChat databases into plaintext.

Install only if you are comfortable reviewing and controlling which scripts run. Avoid running decrypt_db.py unless you intend to decrypt more than favorite.db, keep decrypted outputs and CSV exports protected, use SAFE_MODE for local-only workflows, and only enable LLM, IMA, or Notion exports after confirming exactly what data and credentials will be sent.

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 (5)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/decrypt_db.py:128
Finding

Decryption Recursively Expands All Keyed WeChat Databases into Plaintext

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/llm_classify.py:24
Finding

Configurable LLM Endpoint Receives Bearer Credentials and Private Favorite Metadata Without Transport or Host Validation

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/export_favorites.py:84
Finding

Exported CSV Files Are Vulnerable to Spreadsheet Formula Injection

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/export_to_obsidian.py:151
Finding

Unescaped Favorite Metadata Can Inject Arbitrary Obsidian YAML Frontmatter

Content
View full analysis
str: """生成 YAML frontmatter""" fm_lines = ['---'] fm_lines.append( f'title: "{favorite.title.replace(chr(34), chr(92)+chr(34))}"' ) if favorite.url: fm_lines.append(f'url: "{favorite.url}"') if favorite.category: fm_lines.append(f'category: "{favorite.category}"') if favorite.tags: tags_str = ', '.join([f'"{t}"' for t in favorite.tags]) fm_lines.append(f'tags: [{tags_str}]') if favorite.author: fm_lines.append(f'author: "{favorite.author}"') if favorite.source: fm_lines.append(f'source: "{favorite.source}"') if favorite.nickname: fm_lines.append(f'nickname: "{favorite.nickname}"') if favorite.create_time: try: dt = datetime.fromisoformat( favorite.create_time.replace('Z', '+00:00') ) fm_lines.append(f'created: {dt.strftime("%Y-%m-%d %H:%M")}') except: fm_lines.append(f'created: "{favorite.create_time}"') fm_lines.append( f'imported: {datetime.now().strftime("%Y-%m-%d %H:%M")}' ) fm_lines.append('---') return '\n'.join(fm_lines) ``` ### Technical Analysis The implementation creates YAML through string concatenation rather than a YAML serializer. Only double quotes in the title are partially escaped. Newlines, backslashes, control characters, and quotes in URLs, categories, tags, authors, source names, nicknames, and fallback timestamps are not safely encoded. An embedded newline can terminate the intended scalar and insert additional frontmatter properties. A crafted value containing `---` on its own line can also terminate the frontmatter early and inject Markdown content. This does not i ...[truncated 1206 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/import_ima.py:27
Finding

IMA API Secrets Can Be Exposed Through Command-Line Arguments

Content
View full analysis
...`. 2. The shell records the command in history or exposes it through process inspection. 3. A local attacker, support bundle, monitoring agent, or log collector retrieves the command line. 4. The attacker extracts the IMA API key. ...[truncated 480 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (51)

Tainted flow: 'req' from os.environ.get (line 128, 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/auto_discover.py (reported line 139)May include surrounding context.

python
},
            method="POST"
        )
        with urllib.request.urlopen(req, timeout=60) as resp:
            if resp.status != 200:
                print(f"[ERROR] API 返回 {resp.status}")
                return None

Tainted flow: 'req' from os.environ.get (line 129, 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/import_ima.py (reported line 139)May include surrounding context.

python
},
        method="POST"
    )
    resp = urllib.request.urlopen(req, timeout=120)
    return json.loads(resp.read())

def main():

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

Critical
Category
Data Flow
Confidence
97% confidence
Finding

The request URL is taken from the LLM_API_URL environment variable and used directly in urllib.request.urlopen, so whoever controls the runtime environment can redirect article content and the bearer API key to an arbitrary endpoint. In this skill, the transmitted payload includes user article metadata and the Authorization header, making this an SSRF/exfiltration primitive rather than a harmless configuration choice.

Content

Scanner excerpt · scripts/llm_classify.py (reported line 212)May include surrounding context.

python
},
            method="POST"
        )
        with urllib.request.urlopen(req, timeout=30) as resp:
            if resp.status != 200:
                return {
                    "local_id": article.get("local_id", ""),

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Undeclared access to credential files under ~/.config/ima/ and network import behavior that is active unless SAFE_MODE is explicitly set contradict the claim that network features are disabled by default. For a skill handling personal content, silent credential discovery plus default-capable outbound import creates a real risk of unintended data exfiltration or account misuse if the skill is invoked without the user understanding those defaults.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

Undeclared access to credential files under ~/.config/ima/ and network import behavior that is active unless SAFE_MODE is explicitly set contradict the claim that network features are disabled by default. For a skill handling personal content, silent credential discovery plus default-capable outbound import creates a real risk of unintended data exfiltration or account misuse if the skill is invoked without the user understanding those defaults.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

Undeclared access to credential files under ~/.config/ima/ and network import behavior that is active unless SAFE_MODE is explicitly set contradict the claim that network features are disabled by default. For a skill handling personal content, silent credential discovery plus default-capable outbound import creates a real risk of unintended data exfiltration or account misuse if the skill is invoked without the user understanding those defaults.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

Undeclared access to credential files under ~/.config/ima/ and network import behavior that is active unless SAFE_MODE is explicitly set contradict the claim that network features are disabled by default. For a skill handling personal content, silent credential discovery plus default-capable outbound import creates a real risk of unintended data exfiltration or account misuse if the skill is invoked without the user understanding those defaults.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

Undeclared access to credential files under ~/.config/ima/ and network import behavior that is active unless SAFE_MODE is explicitly set contradict the claim that network features are disabled by default. For a skill handling personal content, silent credential discovery plus default-capable outbound import creates a real risk of unintended data exfiltration or account misuse if the skill is invoked without the user understanding those defaults.

Content

No source excerpt is available for this finding.

Hidden Instructions

High
Category
Prompt Injection
Confidence
60% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · references/schema.md (reported line 1)May include surrounding context.

md
# favorite.db 数据库结构

## 表:fav_db_item

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script explicitly states it decrypts WeChat 4.0 SQLCipher databases using per-database encryption keys extracted from process memory. That behavior goes beyond the declared purpose of exporting and classifying favorites from an already parsed favorite.db and instead enables recovery of protected data from encrypted databases, which is highly sensitive capability with clear dual-use and abuse potential.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code recursively walks the configured database directory and decrypts every matching .db file for which a key exists, rather than limiting itself to the favorites database described in the skill metadata. This broad collection behavior materially increases the amount and sensitivity of data exposed, expanding from a single export workflow into bulk decryption of potentially unrelated user databases.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The changelog explicitly states that 500 sampled titles from a user's favorites are sent to an LLM for category discovery, but it does not present a clear warning in-line that user content may leave the local environment and be transmitted to a third-party model provider. Because the skill handles personal WeChat favorites, even titles alone can contain sensitive or identifying information, so undocumented external transmission creates a meaningful privacy and consent risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The Notion export section documents bulk import of favorites into a third-party SaaS platform and requests an API token, but it does not clearly warn that user data will be uploaded off-device to Notion. In a skill centered on private saved content and framed as local/privacy-preserving, this omission can mislead users about where their data goes and increase accidental disclosure risk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding

The skill advertises capabilities that involve environment variables, local file reads/writes, and optional network access, but it does not declare any explicit tool scope or allowed-tools boundaries. That omission weakens reviewability and containment, making it easier for an agent runtime to grant broader-than-necessary access to sensitive data such as local databases, API tokens, or exported content.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Broad trigger phrases like '帮我整理微信收藏' can cause the skill to activate in situations where the user intended a general discussion rather than file processing or external export. In a skill with local file and optional network capabilities, accidental invocation increases the chance of unintended access to sensitive personal data or initiation of workflows the user did not mean to run.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

An ambiguous trigger list with high-level phrases and no activation boundaries makes unintentional routing more likely. Because this skill touches personal archives and may use API tokens or remote services, loose triggering meaningfully raises the risk of privacy-impacting actions occurring without sufficiently specific user consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documented LLM second-pass classification prompt explicitly includes article title, source account, and URL, which means user-collected content metadata may be transmitted to an external model provider when the optional networked feature is used. Even if this is framed as optional, the file contains no user-facing warning, consent step, or data-minimization guidance, so users may unknowingly export potentially sensitive reading history and identifiers off-device.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

L037-L041 的注释写的是“安全模式”,并提示“网络功能已禁用,自动归纳不可用”,但代码实际是在检测到 SAFE_MODE 后立即退出整个脚本。该脚本本可在后续阶段先读取和采样本地 CSV,再仅在调用 LLM 时阻止联网;当前实现却把“禁用网络”扩大成“完全不可用”,与注释表达的意图不一致。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script sends sampled bookmark titles and source names to an external LLM service, which may contain sensitive personal, business, or research information. In the context of a WeChat favorites export tool, the data is especially likely to reflect private reading habits and interests, so transmitting it off-device without a strong user-facing warning or consent materially increases privacy risk.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

User-provided article titles and sources are forwarded verbatim to a third-party LLM, without minimization, masking, or filtering. Because bookmark titles and source accounts can reveal private interests, employers, clients, health topics, or other sensitive associations, this creates unnecessary disclosure risk in a tool whose description emphasizes offline use and optional networking.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

When LLM reclassification is enabled, the script packages low-confidence records and sends article metadata such as title, source account, and URL to the LLM module. In a tool designed around exporting private WeChat favorites and offline-first usage, transmitting user-derived metadata without an explicit, prominent warning and consent step creates a real privacy/data-leak risk, especially if the LLM backend is remote or third-party.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/config.py (reported line 108)May include surrounding context.

python
def _auto_detect_db_dir_linux():
    """自动检测 Linux 微信 db_storage 路径。

    优先搜索当前用户的 home 目录。以 sudo 运行时通过 SUDO_USER 回退到
    实际用户的 home,避免只搜索 /root 而遗漏真实数据目录。
    """
    seen = set()

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/config.py (reported line 116)May include surrounding context.

python
def _auto_detect_db_dir_linux():
    """自动检测 Linux 微信 db_storage 路径。

    优先搜索当前用户的 home 目录。以 sudo 运行时通过 SUDO_USER 回退到
    实际用户的 home,避免只搜索 /root 而遗漏真实数据目录。
    """
    seen = set()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script exports a user's WeChat favorites database into a plaintext CSV on disk, which can contain highly sensitive personal content such as links, descriptions, source identifiers, and app usernames. While this is the stated purpose of the tool, the lack of any privacy warning, consent prompt, output hardening, or guidance about protecting the exported file increases the risk of accidental disclosure on shared systems or through later exfiltration.

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 · scripts/export_to_notion.py (reported line 39)May include surrounding context.

python
logger = logging.getLogger(__name__)

# Notion API 配置
NOTION_API_BASE = "https://api.notion.com/v1"
NOTION_API_VERSION = "2022-06-28"

Static analysis

Detected: suspicious.exposed_secret_literal, suspicious.secret_argv_exposure

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/import_ima.py:69

Instructions pass high-value credentials through process argv.

Critical
Code
suspicious.secret_argv_exposure
Location
SKILL.md:151