Back to skill

Security audit

微信聊天记录智能整理

Security checks for vulnerabilities and agentic risk

Overview

The skill is broadly consistent with organizing WeChat chats, but it handles private messages while asking users to install and run a third-party CLI with root and Full Disk Access.

Install only if you are comfortable giving a third-party WeChat CLI broad local access to private messages. Prefer a pinned, verified package, avoid running it with sudo unless the publisher clearly justifies why, grant the narrowest possible macOS permissions, review extracted chat content before saving it to Obsidian or calendars, and be aware that Obsidian vaults may sync or share those notes.

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

T08 · Insecure Dependencies

Error
Location
SKILL.md:43
Finding

Unpinned Third-Party Package Installation Followed by Privileged Execution

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:43-52; additional occurrence in references/commands.md:134-139
Vulnerability Type: Supply-chain compromise through unpinned dependencies
Risk Level: High

Vulnerable Code

bash
which wechat-cli
bash
npm install -g @canghe_ai/wechat-cli
# or
pip install wechat-cli
bash
sudo wechat-cli init

Technical Analysis

The skill instructs users to install a mutable package from either npm or PyPI without specifying an exact version, integrity hash, trusted source repository, or signature. The npm and PyPI package names also differ, and the project does not establish that they are equivalent or maintained by the same trusted publisher.

After installation, the resulting executable is invoked using sudo. This creates a supply-chain trust boundary in which package installation scripts or the installed command can execute attacker-controlled code, potentially with root privileges. Because the dependency source is not included in the audited project, its behavior cannot be independently verified by this audit.

Attack Path

  1. An attacker compromises the package publisher account, package registry entry, or upstream release process.
  2. Alternatively, an unsafe or unrelated package is published under one of the documented names.
  3. A user follows the skill instructions and installs the latest mutable package globally.
  4. Malicious package lifecycle hooks may execute during installation.
  5. The user then executes sudo wechat-cli init.
  6. Malicious code in the installed executable runs with root privileges and can access or modify protected resources.

Impact Assessment

Successful exploitation could result in arbitrary code execution. Global package installation affects the user's broader development environment, while subsequent execution with sudo could permit system-wide file modification, credential theft, install ...[truncated 90 chars]

Remediation
View remediation

Remediation Suggestions

  • Identify and document one canonical, verified package and its official source repository.
  • Pin an exact reviewed package version rather than installing the latest release.
  • Verify package integrity using registry checksums, lockfiles, signed releases, or published hashes.
  • Do not present unrelated npm and PyPI packages as interchangeable without verification.
  • Disable package installation scripts where supported and review all required lifecycle hooks.
  • Avoid global installation when a dedicated virtual environment or isolated local installation is sufficient.
  • Remove the sudo invocation and perform initialization as an unprivileged user whenever possible.
  • If privileged setup is unavoidable, use a small, separately reviewed helper with narrowly defined operations rather than running the entire third-party CLI as root.

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:50
Finding

Excessive Root and Full-Disk Permission Guidance

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:50-54 and SKILL.md:286-290; additional guidance in references/commands.md:126-139
Vulnerability Type: Violation of least privilege
Risk Level: High

Vulnerable Code

bash
sudo wechat-cli init

The accompanying instructions require macOS users to grant the terminal application Full Disk Access.

Technical Analysis

The skill combines root execution with terminal-wide Full Disk Access. Full Disk Access applies to the entire terminal application and, consequently, to other commands and processes launched through that terminal. It is not restricted to the exact WeChat database or Obsidian paths required by the task.

Running the third-party CLI through sudo further expands its authority from access to user-owned chat data to system-level privileges. This violates least-privilege principles because the skill does not demonstrate that every initialization operation requires root access or that terminal-wide access is necessary.

Attack Path

  1. A user grants Full Disk Access to the terminal application as instructed.
  2. The user installs or invokes wechat-cli and executes its initialization command with sudo.
  3. A compromised CLI, dependency, shell configuration, or unrelated terminal process inherits access to protected personal files.
  4. Code executed through sudo additionally obtains root-level authority.
  5. The process reads unrelated private data or modifies protected system resources beyond the task's intended scope.

Impact Assessment

Full Disk Access can expose unrelated private information, including application databases, messages, documents, backups, and other protected user files. Root execution may permit system-wide changes, access to other users' data, tampering with security settings, or complete host compromise. The precise impact depends on the behavior of the externally installed CLI.

Remediation
View remediation

Remediation Suggestions

  • Remove the blanket instruction to grant Full Disk Access to a general-purpose terminal.
  • Use a dedicated, minimally privileged executable or process when protected-file access is unavoidable.
  • Request access only to the exact WeChat files or directories required for the operation.
  • Run initialization as the current user unless a documented operation strictly requires elevation.
  • If elevation is indispensable, separate privileged operations into a narrowly scoped and reviewed helper.
  • Explain precisely which resources require access, why they require it, and how users can revoke access afterward.
  • Validate that all read-only workflows remain read-only and do not request unnecessary write or administrative permissions.

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/save_to_obsidian.py:112
Finding

Chat-Specific Attachment Operation Recursively Scans All WeChat Attachments

Content
View full analysis

Vulnerability Details

File Location: scripts/save_to_obsidian.py:112-132
Vulnerability Type: Overbroad filesystem enumeration
Risk Level: Medium

Vulnerable Code

python
def copy_wechat_attachments(chat_name: str, obsidian_path: str, category: str):
    """From the local WeChat directory, copy attachments into Obsidian."""
    wechat_base = os.path.expanduser(
        "~/Library/Containers/com.tencent.xinWeChat/Data/Documents/xwechat_files/"
    )

    # Find every file
    all_files = []
    for root, dirs, files in os.walk(wechat_base):
        for file in files:
            if file.endswith(('.pdf', '.docx', '.epub', '.mp3', '.txt')):
                all_files.append(os.path.join(root, file))

    if not all_files:
        print("No files were found in the local WeChat directory.")
        return

    target_dir = os.path.join(obsidian_path, category)
    os.makedirs(target_dir, exist_ok=True)

    print(f"Found {len(all_files)} files; manually select the files to copy.")
    print(f"Suggested destination: {target_dir}")

Technical Analysis

The function accepts a chat_name parameter but never uses it to restrict the search. Instead, os.walk recursively traverses the entire xwechat_files directory and enumerates supported attachment types from every accessible conversation or account.

The documented interface presents the operation as chat-specific, but the implementation exceeds that declared scope. The current function only stores paths in memory and reports a count; it does not copy or transmit the files. Nevertheless, it unnecessarily enumerates unrelated private attachments and establishes an overbroad collection primitive that could be expanded or misused later.

Attack Path

  1. A user invokes copy-attachments for one named chat or group.
  2. The supplied chat_name is accepted but ignored.
  3. The function recursively traverses the complete WeChat ...[truncated 655 chars]
Remediation
View remediation

Remediation Suggestions

  • Resolve the requested chat to a validated, canonical attachment directory before beginning traversal.
  • Traverse only the resolved directory for that chat rather than the entire WeChat storage root.
  • Reject empty, unknown, ambiguous, or unmappable chat identifiers.
  • Verify with os.path.realpath that the resolved directory remains under the expected WeChat root.
  • Avoid following symbolic links that escape the authorized directory.
  • Require explicit confirmation before accessing attachments from more than one conversation.
  • Remove or disable the operation until a reliable chat-to-storage mapping is implemented.
  • Add tests proving that a request for one chat cannot enumerate files from another chat.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/save_to_obsidian.py:86
Finding

Untrusted Chat Content Is Embedded in Obsidian Markdown and YAML Without Escaping

Content
View full analysis

Vulnerability Details

File Location: scripts/save_to_obsidian.py:86-105; related note generation in scripts/extract_key_info.py:112-139
Vulnerability Type: Markdown and YAML content injection
Risk Level: Medium

Vulnerable Code

python
def generate_obsidian_todo_template(todos: List[Dict]) -> str:
    """Generate an Obsidian todo-note template."""
    now = datetime.now().strftime('%Y-%m-%d %H:%M')

    content = f"""---
type: wechat-todo
source: {todos[0]['chat'] if todos else 'Unknown'}
created: {now}
tags: [WeChat, Todo]
---

# WeChat Todo Items

> Todo items extracted from WeChat chat history

## Extraction Time
{now}

## Todo List

"""

    for i, todo in enumerate(todos, 1):
        content += f"- [ ] **{todo.get('sender', 'Unknown')}**: {todo.get('content', '')}\n"
        content += f"  - Source: {todo.get('chat', '')} | {todo.get('time', '')}\n\n"

    return content

Related generation logic also directly interpolates untrusted values:

python
note = f"""---
type: wechat-extract
source: {items[0]['chat'] if items else 'Unknown'}
category: {data_type}
created: {now}
tags: [WeChat, {data_type}]
---
"""

note += f"> {item.get('content', '')}\n\n"
if item.get('url'):
    note += f"- Link: {item.get('url')}\n"

Technical Analysis

Chat names, sender names, message contents, categories, and URLs originate from untrusted conversation data. These values are inserted directly into YAML frontmatter and Obsidian Markdown without quoting, escaping, newline normalization, URL-scheme validation, or structural serialization.

A crafted chat name containing newlines can terminate or modify a YAML scalar and inject additional frontmatter fields. Crafted message content can introduce Markdown links, images, embeds, HTML, tasks, or Obsidian-specific constructs. The exact active behavior depends on Obsidian configuration and installed plugins, but t ...[truncated 1201 chars]

Remediation
View remediation

Remediation Suggestions

  • Generate frontmatter through a safe YAML serializer rather than string interpolation.
  • Force attacker-controlled YAML values to be quoted scalar strings.
  • Normalize or reject embedded control characters and newlines in metadata fields.
  • Render message bodies inside inert fenced blocks or escape Markdown and Obsidian-specific syntax.
  • Validate URL schemes and allow only explicitly supported schemes such as https.
  • Reject javascript, data, file, application-specific, and unknown URL schemes.
  • Consider disabling raw HTML and active plugin syntax in imported notes.
  • Preserve original content separately from rendered content when exact archival fidelity is required.
  • Add tests containing multiline chat names, YAML delimiters, Markdown images, HTML, wiki embeds, and plugin command syntax.
Vulnerability Patterns
  • 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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (23)

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The skill description says it organizes WeChat records, but it also instructs reading local Obsidian configuration and, per the finding, enumerating local attachment directories without clearly declaring those broader local-access behaviors. Undeclared local configuration/file discovery is risky in a privacy-sensitive skill because users may not expect filesystem scanning beyond the stated task.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The skill description says it organizes WeChat records, but it also instructs reading local Obsidian configuration and, per the finding, enumerating local attachment directories without clearly declaring those broader local-access behaviors. Undeclared local configuration/file discovery is risky in a privacy-sensitive skill because users may not expect filesystem scanning beyond the stated task.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill documents reading local WeChat data and writing extracted content into Obsidian notes, but it does not declare any explicit tool scope such as allowed file read/write permissions. That creates unclear and overly broad capability boundaries for a privacy-sensitive workflow handling chat logs and local files, increasing the chance of unintended file access or modification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill handles highly sensitive private chat content and proposes writing derived data into notes and creating calendar entries, yet it does not prominently warn that this can expose message contents or modify user data. In this context, missing privacy and modification warnings materially increase the risk of users authorizing actions without informed consent.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
96% confidence
Finding

The documented use of sudo requests root execution for a workflow that processes personal chat data. In a consumer productivity context, unnecessary elevation is especially dangerous because it can grant a third-party CLI unrestricted access to system files and sensitive application data.

Content

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

首次使用需要初始化:

bash
sudo wechat-cli init

⚠️ macOS 用户需要授予终端「完全磁盘访问权限」

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The instruction to run sudo wechat-cli init introduces privileged execution for a skill whose purpose is chat organization, not system administration. Encouraging users to invoke root privileges expands blast radius: a compromised or buggy CLI could alter protected files, install persistence, or expose sensitive local data with elevated access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The example workflow writes extracted chat content to a hard-coded Obsidian path without a confirmation or review step. Because the content originates from private messages, direct persistence to local notes can unintentionally leak sensitive information into a broader knowledge base or overwrite existing files.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
95% confidence
Finding

Repeating guidance to use sudo wechat-cli init in the notes section normalizes privileged execution and increases the likelihood users will run the command without scrutiny. Combined with instructions to grant full disk access, this materially increases the potential impact of a malicious or vulnerable CLI.

Content

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

md
1. **隐私保护**:微信数据仅本地处理,不上传任何数据
2. **微信运行要求**:执行命令时微信需处于运行状态
3. **权限要求**:macOS 需授予「完全磁盘访问权限」
4. **首次使用**:先运行 `sudo wechat-cli init` 初始化
5. **Obsidian 路径检测**:**必须先检测 Obsidian vault 的实际路径**,不要假设为 `~/Obsidian/`
   - 读取 `~/Library/Application Support/obsidian/obsidian.json`
   - 解析 `vaults` 字段获取实际路径

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
95% confidence
Finding

Listing sudo wechat-cli init as routine error recovery encourages users to solve failures by escalating privileges rather than diagnosing the actual cause. That pattern is unsafe in a skill that touches private local data because it turns ordinary troubleshooting into a high-impact privileged action.

Content

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

md
| 错误信息 | 解决方案 |
|---------|---------|
| "微信未运行" | 启动微信后重试 |
| "需要初始化" | 运行 `sudo wechat-cli init` |
| "权限被拒绝" | 检查终端是否具有完全磁盘访问权限 |
| "找不到联系人" | 使用 `wechat-cli sessions` 确认正确的联系人名称 |

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The commands enable reading, searching, exporting, and analyzing personal WeChat messages at scale, but the documentation provides no privacy notice, consent guidance, retention limits, or handling safeguards for sensitive personal data. In the context of a chat-organizer skill, this omission makes accidental overcollection, unauthorized processing, and unsafe downstream storage in notes or calendars more likely.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation tells users to grant Full Disk Access and, on macOS, run initialization with sudo, but does not justify why such broad privileges are necessary or warn about the security consequences. In a skill centered on reading and organizing private chat records, expanding terminal privileges materially increases the blast radius of misuse, compromise, or operator error and could expose far more data than intended.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The macOS instruction to grant Full Disk Access to the terminal expands that terminal’s access to potentially all user data, but the file gives no warning about the implications. Because this skill processes sensitive chat content, the lack of caution is especially dangerous: any command run from that terminal session, malicious or mistaken, could access much broader data than users expect.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
97% confidence
Finding

Recommending sudo wechat-cli init encourages root execution of a chat-processing tool without explaining the necessity or limiting the privileged actions. If the tool, its dependencies, or adjacent shell context are compromised, running as root can lead to full system impact rather than just access to the user’s WeChat data.

Content

Scanner excerpt · references/commands.md (reported line 135)May include surrounding context.

初始化失败

bash
# macOS
sudo wechat-cli init

# Windows
wechat-cli init

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script explicitly extracts contact details such as phone numbers, email addresses, and WeChat IDs from chat messages and includes them in structured output without any consent gate, minimization, masking, or warning. In the context of a skill designed to read private WeChat chats and store or forward extracted data, this increases privacy and data-handling risk because sensitive personal information can be propagated into notes or downstream systems unintentionally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script persists extracted WeChat chat content into an automatically detected Obsidian vault without an explicit consent, sensitivity warning, or destination review step. In this skill context, the data likely contains private messages, contacts, tasks, and schedules, so silent storage can cause unintended disclosure into synced notes, backups, or shared vaults.

Content

No source excerpt is available for this finding.

Tainted flow: 'filepath' from input (line 194, user input) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/save_to_obsidian.py (reported line 82)May include surrounding context.

python
filepath = os.path.join(category_path, filename)
    
    # 写入文件
    with open(filepath, 'w', encoding='utf-8') as f:
        f.write(content)
    
    return filepath

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The attachment-copy feature scans the local WeChat container and enumerates files from a privacy-sensitive directory without clearly warning the user about the scope of access. Even though it does not automatically copy everything, directory-wide discovery of personal documents and media can expose sensitive metadata and normalize overbroad access to local private files.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

Earlier sections repeatedly state that the skill must not assume ~/Obsidian/ and must first read obsidian.json to determine the actual vault path. The later example contradicts that guidance by writing to a hardcoded ~/Obsidian/... path, creating an intent-code/documentation divergence within the skill file.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest frames the skill around reading chats, extracting key information, storing to Obsidian, and creating calendar events. This command reference additionally documents broader data-access and export operations such as contact detail lookup, group member listing, favorites access, and arbitrary file export, which expand the skill from 'organizer' behavior into general WeChat data browsing/export.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The file's natural-language description and user-visible error messages are Chinese-only, which imposes a language constraint on users. The policy allows locale constraints when users are given a choice or when the restriction is clearly documented and justified, neither of which appears here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The error messages printed to stderr are only in Chinese, forcing a specific language for operational feedback. There is no visible mechanism for language selection and no documented reason for restricting the interface to Chinese.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

All user-facing prompts, help text, and status messages are written only in Chinese, which imposes a fixed language choice in the skill's natural-language interface. There is no indication of user opt-in, locale selection, or documentation that this skill is intentionally limited to Chinese-speaking users.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

In the 'meetings' branch, the code reads meeting/date data and creates a note titled '微信会议备忘', but line L203 explicitly comments that it should use a meeting template while actually calling generate_obsidian_todo_template(). This is a direct contradiction between the code's stated intent and implemented behavior, causing meeting data to be formatted as todo content.

Content

No source excerpt is available for this finding.