Back to skill

Security audit

md2WeChat-python

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it advertises, but draft mode can upload local files referenced by Markdown to WeChat without strong path limits or confirmation.

Install only if you trust the Markdown files you process and understand that --draft sends article content and images to WeChat. Avoid running draft mode on untrusted documents until image paths are restricted to the article directory, uploads are confirmed before transmission, preview HTML is sanitized, and dependencies are pinned.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/md_converter.py:327
Finding

Markdown Image Paths Can Disclose Files Outside the Article Directory

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/html_formatter.py:92
Finding

Insufficient HTML Sanitization Allows Active Content in Local Previews

Content
View full analysis
\n\n" ``` ```python output_path.write_text(preview_html, encoding='utf-8') ``` ### Technical Analysis The Markdown parser accepts raw HTML, while the formatter implements only a narrow blocklist. Removing `script` elements does not remove other active content, including: - Event-handler attributes such as `onerror`, `onclick`, and `onload` - Dangerous URL schemes such as `javascript:` - Active or embedding elements not covered by the blocklist - Browser-sensitive attributes on otherwise permitted elements For example, raw Markdown HTML containing an image with an `onerror` handler can survive conversion because neither the tag nor its event attribute is removed. The generated preview is then a stored HTML payload. If a user opens that preview in a browser, the handler can execute in the preview's local-file origin. Article titles are also interpolated into HTML without escaping, creating an additional markup-injection surface. ### Attack Path 1. An attacker supplies a Markdown file containing raw active HTML, for example: ```html ``` 2. The Markdown library preserves the raw HTML. 3. `HTMLFormatter` removes ...[truncated 1013 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/wechat_client.py:219
Finding

Predictable Shared Temporary Filename Enables Symlink-Based File Overwrite

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:4
Finding

Broad Unhashed Dependency Constraints Create Supply-Chain Risk

Content
View full analysis
=1.8.18 markdown>=3.4 beautifulsoup4>=4.12 requests>=2.28 python-dotenv>=1.0 Pillow>=9.0 cryptography>=40.0 ``` ### Technical Analysis Every dependency uses a broad lower-bound constraint and none has an integrity hash. Installation can therefore select future releases that did not exist when the Skill was audited. This does not establish that any listed package is malicious. However, it prevents reproducible installation and increases exposure to compromised releases, unexpected dependency changes, or newly introduced vulnerabilities. Python package installation and import can execute package-controlled code with the privileges of the user installing or running the Skill. ### Attack Path 1. A future dependency release satisfying one of the broad constraints is compromised or introduces unsafe behavior. 2. A user installs the Skill dependencies at a later date. 3. The package resolver selects the affected release because no upper bound, exact pin, or lock file prevents it. 4. Package-controlled code executes during installation or when imported by the Skill. 5. The compromised dependency gains the privileges of the installing or executing user. ### Impact Assessment The potential scope is the account and environment used to install or run the Skill. A compromised dependency could access the same files, environment variables, and network resources available to the process, including the WeChat credentials used in draft mode. No current dependency compromise was demonstrated during this static audit; this finding concerns preventable supply-chain exposure and build reproducibility. ]]>
Remediation
View remediation
Vulnerability Patterns
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (37)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

声明描述的是一个端到端能力:Markdown 解析与排版、元数据支持、图片上传,以及发送到微信公众号草稿箱。给出的代码片段实际只是一个 HTML 格式化器,用于把已有 HTML 调整为适配微信公众号的内联样式形式。它没有 Markdown 解析、没有任何网络/API 调用、没有图片上传、没有 Front Matter 处理,也没有表格专门处理逻辑。代码行为与声明中的一部分“微信公众号兼容的内联样式 HTML”相符,但无法覆盖其核心宣称的完整转换和一键发送能力,因此属于明显描述与实际行为不一致。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

该代码与声明的前半部分基本一致:确实完成 Markdown→微信公众号兼容内联样式 HTML 的转换,并支持 Front Matter、表格、代码块、列表,以及在有 publisher 时上传正文内本地图片并替换为微信 URL。还会生成本地预览 HTML、清理微信不兼容字符并处理超长内容。但声明中的关键能力“一键发送到微信草稿箱”在此代码块中没有实现:没有看到创建草稿、调用微信草稿接口、提交文章到远端草稿箱等行为,仅构造并返回包含 title/content/author/summary 等字段的字典。因此描述高估了该代码块的实际能力,构成描述与行为不一致。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

声明的核心用途是“将 Markdown 文件转换为微信公众号兼容的内联样式 HTML,并发送到微信草稿箱”,这是一个包含内容解析与排版转换的完整工作流。但该代码片段实际只覆盖微信公众号 API 交互部分:令牌管理、图片上传、草稿创建、默认封面生成和连接测试。它接收的 article['content'] 似乎应当已经是现成 HTML/内容,代码本身没有读取 Markdown 文件、没有 Markdown 解析、没有 CSS 内联、没有 Front Matter 提取,也没有实现表格、代码块、列表等排版转换逻辑。因此该代码行为只匹配声明中的“发送到微信草稿箱、图片上传”部分,而缺失了声明中更主要的 Markdown 转换与排版能力,属于明显的描述与实际行为不一致。

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
# md2wechat-skill 环境变量配置模板
# 将此文件复制为 .env 并填写真实值

# ──────────────────────────────────────────
# 微信公众号配置(必填)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
# md2wechat-skill 环境变量配置模板
# 将此文件复制为 .env 并填写真实值

# ──────────────────────────────────────────
# 微信公众号配置(必填)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
# md2wechat-skill 环境变量配置模板
# 将此文件复制为 .env 并填写真实值

# ──────────────────────────────────────────
# 微信公众号配置(必填)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
# md2wechat-skill 环境变量配置模板
# 将此文件复制为 .env 并填写真实值

# ──────────────────────────────────────────
# 微信公众号配置(必填)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
# md2wechat-skill 环境变量配置模板
# 将此文件复制为 .env 并填写真实值

# ──────────────────────────────────────────
# 微信公众号配置(必填)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · resources/env_template.txt (reported line 2)May include surrounding context.

text
# md2wechat-skill 环境变量配置模板
# 将此文件复制为 .env 并填写真实值

# ──────────────────────────────────────────
# 微信公众号配置(必填)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/md2wechat.py (reported line 15)May include surrounding context.

python
# md2wechat-skill 环境变量配置模板
# 将此文件复制为 .env 并填写真实值

# ──────────────────────────────────────────
# 微信公众号配置(必填)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/md2wechat.py (reported line 16)May include surrounding context.

python
# md2wechat-skill 环境变量配置模板
# 将此文件复制为 .env 并填写真实值

# ──────────────────────────────────────────
# 微信公众号配置(必填)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/md2wechat.py (reported line 34)May include surrounding context.

python
# md2wechat-skill 环境变量配置模板
# 将此文件复制为 .env 并填写真实值

# ──────────────────────────────────────────
# 微信公众号配置(必填)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/md2wechat.py (reported line 41)May include surrounding context.

python
# md2wechat-skill 环境变量配置模板
# 将此文件复制为 .env 并填写真实值

# ──────────────────────────────────────────
# 微信公众号配置(必填)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/md2wechat.py (reported line 61)May include surrounding context.

python
# md2wechat-skill 环境变量配置模板
# 将此文件复制为 .env 并填写真实值

# ──────────────────────────────────────────
# 微信公众号配置(必填)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/md2wechat.py (reported line 77)May include surrounding context.

python
# md2wechat-skill 环境变量配置模板
# 将此文件复制为 .env 并填写真实值

# ──────────────────────────────────────────
# 微信公众号配置(必填)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/md2wechat.py (reported line 159)May include surrounding context.

python
# md2wechat-skill 环境变量配置模板
# 将此文件复制为 .env 并填写真实值

# ──────────────────────────────────────────
# 微信公众号配置(必填)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README explicitly advertises uploading article content, embedded local images, and cover images to WeChat, but it does not warn users that this transmits potentially sensitive local data to a third-party platform and stores it remotely as drafts or media. In a publishing skill, this behavior is expected, but the lack of a clear privacy/data-transfer notice can lead users to unintentionally exfiltrate confidential content or images.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The entire article, including the title, authoring, and instructional content, is written exclusively in Chinese with no indication that language choice is optional. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module title and class docstring are written only in Chinese and explicitly target WeChat public-account formatting, which imposes a single language/locale context without offering a user choice or opt-in. The policy for this audit flags language or locale constraints when they are forced rather than optionally selected or clearly justified as user-configurable.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The image handling code automatically uploads any locally referenced image in the rendered HTML to WeChat when a publisher object is supplied, which causes local file contents to be transmitted to an external service. In the context of a Markdown-to-WeChat publishing skill, this behavior is expected for functionality, but it is still a real privacy and data-exfiltration risk because there is no explicit consent gate, allowlist, or warning at the point of transfer.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This file's docstrings, prompts, status messages, and error text are consistently presented in Chinese, including operational and failure notices shown to users. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly documented and justified, which it is not here.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/wechat_client.py (reported line 105)May include surrounding context.

python
try:
            import requests
            url = f"https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token={self.client.access_token}"
            with open(image_path, 'rb') as f:
                files = {'media': f}
                resp = requests.post(url, files=files)

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/wechat_client.py (reported line 192)May include surrounding context.

python
try:
            import requests
            url = f"https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token={self.client.access_token}"
            with open(image_path, 'rb') as f:
                files = {'media': f}
                resp = requests.post(url, files=files)

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency is specified with only a lower bound, so builds may resolve to different versions over time and can unexpectedly pull in vulnerable or breaking releases. In a skill that publishes content to WeChat and processes Markdown/HTML, supply-chain drift increases the risk of introducing exploitable parser or network-library flaws without any code change in the repository.

Content

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

text
# md2wechat-skill Python 依赖
# 安装命令:pip install -r requirements.txt

wechatpy>=1.8.18
markdown>=3.4
beautifulsoup4>=4.12
requests>=2.28

Static analysis

No suspicious patterns detected.