Back to skill

Security audit

wechat-article-to-markdown

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real WeChat-to-Markdown converter, but article content can cause it to fetch arbitrary image URLs and save unbounded remote content locally, so it needs review before installation.

Install only if you are comfortable running a headless browser and a network-fetching converter on WeChat article URLs you trust. Avoid using it in environments with access to private internal services or sensitive local networks, and watch disk usage because downloaded image responses are not bounded. A safer release would restrict image hosts to WeChat-controlled CDNs, validate redirects and private IP ranges, enforce download size limits, and pin dependencies.

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

Warning
Location
wechat_article_to_markdown.py:92
Finding

Unrestricted Article-Controlled Image Fetching Enables SSRF

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
wechat_article_to_markdown.py:101
Finding

Unbounded Image Downloads Permit Memory, Disk, and Bandwidth Exhaustion

Content
View full analysis
dict[str, str]: """Concurrent download of all images, returning a remote-to-local mapping.""" if not img_urls: return {} print(f"🖼 Downloading {len(img_urls)} images " f"(concurrency {IMAGE_CONCURRENCY})...") semaphore = asyncio.Semaphore(IMAGE_CONCURRENCY) async with httpx.AsyncClient() as client: tasks = [ download_image(client, url, img_dir, i + 1, semaphore) for i, url in enumerate(img_urls) ] results = await asyncio.gather(*tasks) ``` ### Technical Analysis Each response is fully buffered through `resp.content` before it is written to disk. No maximum response size, aggregate download size, image count, or accepted content type is enforced. The semaphore limits simultaneous downloads to five, but it does not constrain: - The total number of scheduled download tasks - The size of any individual response - The total memory consumed by concurrent buffered responses - The total amount of disk space written - The aggregate network bandwidth consumed The inferred filename extension is derived from the URL rather than a verified image MIME type. Therefore, a destination can return arbitrary large content while appearing to be an image URL. ### Attack Path 1. An attacker supplies an article containing many unique image elements or image URLs that return very l ...[truncated 965 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
pyproject.toml:9
Finding

Unpinned Third-Party Dependencies Create Supply-Chain Exposure

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • 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
Findings (19)

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 12)May include surrounding context.

md
- Anti-detection fetching with Camoufox
- Extract article metadata (title, account name, publish time, source URL)
- Convert WeChat article HTML to Markdown
- Download article images to local `images/` and rewrite links
- Handle WeChat `code-snippet` blocks with language fences

## Installation

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 85)May include surrounding context.

.agents/skills/wechat-article-to-markdown

Or copy SKILL.md only

curl -o .agents/skills/wechat-article-to-markdown/SKILL.md
https://raw.githubusercontent.com/jackwener/wechat-article-to-markdown/main/SKILL.md

text

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 92)May include surrounding context.

.agents/skills/wechat-article-to-markdown

Or copy SKILL.md only

curl -o .agents/skills/wechat-article-to-markdown/SKILL.md
https://raw.githubusercontent.com/jackwener/wechat-article-to-markdown/main/SKILL.md

text

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 151)May include surrounding context.

.agents/skills/wechat-article-to-markdown

Or copy SKILL.md only

curl -o .agents/skills/wechat-article-to-markdown/SKILL.md
https://raw.githubusercontent.com/jackwener/wechat-article-to-markdown/main/SKILL.md

text

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
85% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 91)May include surrounding context.

bash
# Claude Code user-level skills directory (global)
mkdir -p ~/.claude/skills/wechat-article-to-markdown
curl -o ~/.claude/skills/wechat-article-to-markdown/SKILL.md \
  https://raw.githubusercontent.com/jackwener/wechat-article-to-markdown/main/SKILL.md

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
85% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 150)May include surrounding context.

bash
# Claude Code user-level skills directory (global)
mkdir -p ~/.claude/skills/wechat-article-to-markdown
curl -o ~/.claude/skills/wechat-article-to-markdown/SKILL.md \
  https://raw.githubusercontent.com/jackwener/wechat-article-to-markdown/main/SKILL.md

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill explicitly instructs installation and execution of a CLI that fetches remote content from the network and writes Markdown and images to local disk, yet the manifest declares no permissions or allowed-tools scope. That creates a real security transparency and containment issue: operators cannot easily review or restrict the skill's expected network and file-write behavior before use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README shows the output directory structure and earlier states that article images are downloaded locally, but it does not explicitly warn users that running the tool will create local directories and save fetched content from a remote URL. For a markdown skill description, file writes affecting user workspace should be clearly disclosed as behavior that may affect local data or filesystem state.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill states the output paths, but it does not clearly warn users in the description/usage flow that running it will persist full article content and downloaded images to local storage. This can lead to accidental retention of copyrighted, sensitive, or unexpected content on disk, especially in automated workflows.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: setuptools has 10 known advisory(ies) (CVE-2013-1633 (Setuptools vulnerable to Man-in-the-middle attacks); CVE-2025-47273 (setuptools has a path traversal vulnerability in PackageIndex.download that lead); CVE-2024-6345 (setuptools vulnerable to Command Injection via package URL) +7 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: wheel has 4 known advisory(ies) (CVE-2026-24049 (Wheel Affected by Arbitrary File Permission Modification via Path Traversal in w); CVE-2022-40898 (pypa/wheel vulnerable to Regular Expression denial of service (ReDoS)); CVE-2022-40898 (An issue discovered in Python Packaging Authority (PyPA) Wheel 0.37.1 and earlie) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: markdownify has 2 known advisory(ies) (CVE-2025-46656 (markdownify allows large headline prefixes such as <h9999999>, which causes memo); CVE-2025-46656 (markdownify allows large headline prefixes such as <h9999999>, which causes memo)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: httpx has 2 known advisory(ies) (CVE-2021-41945 (Improper Input Validation in httpx); CVE-2021-41945 (Encode OSS httpx <=1.0.0.beta0 is affected by improper input validation in `http)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency 'markdownify' is unpinned, so installs may resolve to different versions over time, including newly introduced vulnerable or breaking releases. In a tool that fetches remote WeChat article content and transforms HTML to Markdown, supply-chain unpredictability increases risk because parsing behavior directly affects untrusted input handling.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
camoufox[geoip]
markdownify
beautifulsoup4
httpx

Unverifiable Dependency: markdownify has 2 known advisory(ies) (CVE-2025-46656 (markdownify allows large headline prefixes such as <h9999999>, which causes memo); CVE-2025-46656 (markdownify allows large headline prefixes such as <h9999999>, which causes memo)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding

'markdownify' has known advisories, and because no version is pinned, it is impossible to verify whether the deployed environment avoids the vulnerable releases. This matters more in this skill than in a generic utility because the package processes attacker-controlled HTML content from remote WeChat articles, so parser/transformer denial-of-service bugs are realistically reachable.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency 'beautifulsoup4' is unpinned, which makes builds non-reproducible and can silently introduce insecure or incompatible versions. Because this skill parses externally sourced HTML from mp.weixin.qq.com, parser dependency drift can materially change security posture and robustness.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
camoufox[geoip]
markdownify
beautifulsoup4
httpx

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency 'httpx' is unpinned, allowing future installs to pull arbitrary newer or older resolver-selected versions, some of which may contain known flaws. Since this package is responsible for network fetching of remote content, version uncertainty directly affects transport and input-validation security.

Content

Scanner excerpt · requirements.txt (reported line 4)May include surrounding context.

text
camoufox[geoip]
markdownify
beautifulsoup4
httpx

Unverifiable Dependency: httpx has 2 known advisory(ies) (CVE-2021-41945 (Improper Input Validation in httpx); CVE-2021-41945 (Encode OSS httpx <=1.0.0.beta0 is affected by improper input validation in `http)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
88% confidence
Finding

'httpx' has known advisories and the manifest does not constrain the installed version, so vulnerable builds may be selected without visibility. Because this skill retrieves remote web content, any input-validation weakness in the HTTP client is more relevant than in an offline-only tool and could expose the agent to malformed response or request-handling issues.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The module description and subsequent user-facing messages indicate the skill is designed to interact in Chinese, and the runtime prints throughout the file are also Chinese-only. This creates a language/locale constraint without any documented user choice or opt-in, which matches the policy-violation category for forced language behavior.

Content

No source excerpt is available for this finding.