Back to skill

Security audit

Wechat Saver

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its WeChat-to-Markdown purpose, but it needs review because it can fetch arbitrary web or embedded image URLs and write downloaded content into local notes without strong validation or limits.

Install only if you are comfortable with a local crawler that downloads remote article text and images into your Obsidian files. Use a dedicated virtual environment, avoid --break-system-packages, choose an explicit output directory, prefer --no-images for untrusted links, and only process links you trust until URL/domain, size, and path validation are added.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/wechat_to_md.py:43
Finding

Server-Side Request Forgery Through Unrestricted Article URLs

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/wechat_to_md.py:404
Finding

Server-Side Request Forgery Through Attacker-Controlled Image Sources

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/wechat_to_md.py:391
Finding

Directory Traversal and File Overwrite Through Remote Article Titles

Content
View full analysis
|]', '', title) safe_title = safe_title[:50] # 限制长度 # 创建文章目录 article_dir = os.path.join(self.output_dir, safe_title) os.makedirs(article_dir, exist_ok=True) # 提取所有图片源(用于下载) image_sources = [(src, idx) for idx, (etype, src, *_) in enumerate(elements) if etype == 'img'] # 处理图片 image_map = {} # src -> relative_path if keep_images and image_sources: print(f"🖼️ 正在处理 {len(image_sources)} 张图片...") images_dir = os.path.join(article_dir, "images") os.makedirs(images_dir, exist_ok=True) for i, (src, _) in enumerate(image_sources): try: print(f" 下载图片 {i+1}/{len(image_sources)}") img_resp = self.session.get(src, timeout=10) if img_resp.status_code == 200: ext = self._get_image_ext(src) filename = f"image_{i+1:03d}.{ext}" filepath = os.path.join(images_dir, filename) with open(filepath, 'wb') as f: f.write(img_resp.content) ``` ### Technical Analysis The remote article title is used as a directory component after removing only this set of characters: ```text \ / : * ? " < > | ``` The sanitizer does not reject the special path components `.` or `..`. If the extracted title is `..`, then: ```text article_dir = /.. images_dir = /../images ``` The operating system normalizes this path when it is used, causing image files to be created outside the intended article directory. Fixed filenames such as `image_001.jpg` are opened with `wb`, so existing files at the resolved destination are overwritten. The Markdown file path is constructed separately under `self.output_dir`, but image output can escape the configured output directory through ...[truncated 1204 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/wechat_to_md.py:43
Finding

Unbounded Remote Response Processing Enables Resource Exhaustion

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:68
Finding

Unpinned Third-Party Dependency Installation

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (3)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill clearly performs network access, shell/package installation steps, and local file writes, but the manifest does not declare any tool scope or permission boundaries. This increases the chance of over-broad execution in an agent environment, where the skill may be invoked with more capabilities than users expect, especially since it downloads remote content and writes it to disk by default.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The description says the tool saves WeChat articles to a local Obsidian knowledge base, but it does not prominently warn that downloaded article text and images are written to the local filesystem by default. In an agent setting, insufficient disclosure can lead to unintended persistence of untrusted remote content, surprising users and increasing the risk of clutter, sensitive data mixing, or accidental storage in synced note repositories.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The package description is entirely in Chinese and describes the tool only in that locale, which can indicate a language-specific constraint without user opt-in. The file does not provide any alternative language option or document a justified region-specific limitation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.