Back to skill

Security audit

WeChat Article to Markdown

Security checks for vulnerabilities and agentic risk

Overview

The skill performs its stated WeChat-to-Markdown task, but its network fetching and image downloading are broader than its claimed WeChat-only scope.

Review before installing. Use this only on trusted WeChat article URLs, prefer --no-images for untrusted pages, choose a contained output directory, and run it in an isolated environment. The publisher should add strict host allowlisting, redirect/IP validation, download size limits, and pinned dependencies before this is treated as low-risk.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/wechat_to_md.py:62
Finding

Arbitrary URL Fetching Enables Server-Side Request Forgery

Content
View full analysis
str: raw = raw.strip() raw = html_unescape(raw) if raw.startswith("//"): raw = "https:" + raw if not raw.startswith("http"): raw = "https://" + raw return raw ``` The normalized URL is passed directly to Playwright: ```python page.goto(url, wait_until="domcontentloaded", timeout=timeout) ``` The fallback request implementation also accepts the URL directly and follows redirects: ```python resp = session.get(url, timeout=20, allow_redirects=True) ``` Both public conversion functions invoke the unrestricted fetch operation: ```python url = normalize_url(url) print(f"[*] 正在抓取: {url}") html = fetch_html(url, use_playwright=use_playwright) ``` ```python url = normalize_url(url) html = fetch_html(url, use_playwright=use_playwright) ``` ### Technical Analysis `normalize_url()` only performs syntactic normalization. It does not verify: - That the URL uses an approved scheme. - That the hostname is exactly `mp.weixin.qq.com`. - That the resolved address is not loopback, private, link-local, reserved, or otherwise internal. - That redirect destinations remain within the permitted domain. - That the URL does not contain embedded credentials or hostname-confusion syntax. This conflicts with the documented claim that the Skill only supports `mp.weixin.qq.com` articles. Both Playwright and `requests` can therefore be directed to arbitrary network locations. The `requests` path explicitly follows redirects, while browser navigation normally follows HTTP redirects as well. The parser also accepts the generic `article` selector as a content containe ...[truncated 1733 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/wechat_to_md.py:300
Finding

Unrestricted and Unbounded Image Downloads Permit Secondary SSRF and Resource Exhaustion

Content
View full analysis
100: # 至少 100 字节 return url, str(filepath) with open(filepath, "wb") as f: for chunk in resp.iter_content(8192): if chunk: f.write(chunk) ``` Image downloading is enabled by default in the main conversion path: ```python if download_imgs and img_urls: print(f"[*] 下载 {len(img_urls)} 张图片...") url_to_local = download_images(img_urls, article_dir) if url_to_local: result = replace_image_urls(result, url_to_local, obsidian_format=obsidian_format) ``` ### Technical Analysis Article HTML is remote and untrusted. Any image URL ...[truncated 2194 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:30
Finding

Runtime Dependencies Are Installed Without Version or Integrity Pinning

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (11)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/wechat_to_md.py "<WECHAT_URL>" -o "<OUTPUT_DIR>"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/wechat_to_md.py "<WECHAT_URL>" -o "<OUTPUT_DIR>"

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · references/wechat-dom-reference.md (reported line 61)May include surrounding context.

3.1 标题

html
<!-- H2 标题 -->
<h2 style="text-align: center; font-size: 22px;">标题文本</h2>

<!-- 自定义标题(通过 section 模拟) -->

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · references/wechat-dom-reference.md (reported line 61)May include surrounding context.

3.1 标题

html
<!-- H2 标题 -->
<h2 style="text-align: center; font-size: 22px;">标题文本</h2>

<!-- 自定义标题(通过 section 模拟) -->

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill instructs the agent to install packages, fetch remote content, download images, and write Markdown/files to disk, but it does not declare any tool scope, permissions, or allowed-tools boundary. This creates an authorization gap where an agent may perform network, shell, and filesystem actions without explicit least-privilege constraints or user-visible guardrails.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill describes automatic image downloading, concurrent network access, URL replacement, and local output behavior, but does not clearly require advance user consent or prominently warn that remote resources will be fetched and files written locally. In an agent setting, that can lead to silent network activity and unintended filesystem modifications, especially when processing untrusted URLs or batch jobs.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The default HTTP headers hard-code Accept-Language to prefer zh-CN, which imposes a specific locale behavior in network requests. The file does not offer users a language/locale choice or explain why this locale restriction is required, which matches the policy's language/locale violation criterion.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The browser automation context explicitly sets locale="zh-CN" and sends Accept-Language: zh-CN,zh;q=0.9, forcing a specific language environment for all page fetches. This is a natural-language locale policy issue because the skill does not let the user choose the locale or document a justified regional limitation.

Content

No source excerpt is available for this finding.

Tainted flow: 'filepath' from requests.get (line 774, network 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/wechat_to_md.py (reported line 782)May include surrounding context.

python
if existing_size > 100:  # 至少 100 字节
                        return url, str(filepath)

                with open(filepath, "wb") as f:
                    for chunk in resp.iter_content(8192):
                        if chunk:
                            f.write(chunk)

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

Several instructional comments and feature descriptions are presented in Chinese while the rest of the skill is in English, but the document does not state that bilingual output is optional or user-selected. This can violate language/locale policy when a skill imposes a language choice without explicit opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The image-handling section uses Chinese-only bullets and inline comments despite the surrounding document being primarily English. Without an explicit user language preference or documented locale constraint, this is a natural-language policy issue.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.