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## 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
## 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## 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
## 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## 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
## 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## 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
## 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.

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.

Lp3

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.

Missing User Warnings

Medium
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.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
首次使用需要初始化:
```bash
sudo wechat-cli init
```

> ⚠️ macOS 用户需要授予终端「完全磁盘访问权限」
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.

Context-Inappropriate Capability

Medium
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.

Missing User Warnings

Medium
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.

Sudo/Root Execution

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

Sudo/Root Execution

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

Missing User Warnings

Medium
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.

Context-Inappropriate Capability

Medium
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.

Missing User Warnings

Medium
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.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
### 初始化失败
```bash
# macOS
sudo wechat-cli init

# Windows
wechat-cli init
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.

Missing User Warnings

Medium
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.

Missing User Warnings

Medium
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.

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

Medium
Category
Data Flow
Content
filepath = os.path.join(category_path, filename)
    
    # 写入文件
    with open(filepath, 'w', encoding='utf-8') as f:
        f.write(content)
    
    return filepath
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.

Missing User Warnings

Medium
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.

Intent-Code Divergence

Low
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.

Description-Behavior Mismatch

Low
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.

Natural-Language Policy Violations

Low
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.

Natural-Language Policy Violations

Low
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.

Natural-Language Policy Violations

Low
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.

Intent-Code Divergence

Low
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.

Static analysis

No suspicious patterns detected.