Back to skill

Security audit

Wechat Collect

Security checks for vulnerabilities and agentic risk

Overview

The skill’s core purpose is coherent, but it fetches user-supplied URLs without an artifact-backed allowlist and can preserve untrusted article text for downstream agents.

Install only if you are comfortable with a collector that contacts external URLs and stores raw article HTML locally. Use it with trusted public WeChat article URLs, avoid feeding arbitrary links, and review generated briefs before passing them to other agents because source article text may contain misleading instructions.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
runtime.py:215
Finding

Unrestricted URL Fetching Enables Server-Side Request Forgery

Content
View full analysis
tuple[str, str]: probe = fetch_page(url, timeout=30) access_meta = classify_page(source_url=url, html_text=probe["html"], final_url=probe["final_url"]) ``` ### Technical Analysis `load_article_html()` passes the supplied URL directly to `fetch_page()` before performing any visible validation of its scheme, hostname, port, resolved IP address, or redirect destination. Although the documentation describes the input as a public `mp.weixin.qq.com` article URL, this restriction is not enforced in the audited code before the network request occurs. Classification after fetching does not prevent the initial request from reaching an unauthorized destination. The implementation also relies on the external `skill_runtime.wechat_access.fetch_page` function for redirect handling. Because that dependency was not included in the supplied project, the audit could not establish that redirects are restricted or that private and reserved network addresses are rejected. ### Attack Path 1. An attacker supplies an input URL pointing to an internal or otherwise restricted HTTP service. 2. The skill passes the URL directly to `fetch_page(url, timeout=30)`. 3. The Agent host sends the request using its own network access. 4. The target can be a loopback service, private network host, link-local cloud metadata endpoint, or another service inaccessible to the attacker directly. 5. The response is passed into page classification and may subsequently be processed, archived, reflected through generated content, or differentiated through errors and timing behavior. 6. Redirects may provide an additional bypass if the initial public URL redirects to a prohibited address and the shared fetch function does not revalidate each destination. ...[truncated 715 chars]
Remediation
View remediation

other

Warning
Location
runtime.py:112
Finding

Untrusted Article Content Can Inject Instructions into Downstream AI Agents

Content
View full analysis
= 28] summary_paragraphs = body_paragraphs[:4] or paragraphs[:4] ``` The extracted content is then placed directly into a Markdown brief intended for downstream writing agents: ```python def build_brief_markdown(article: dict[str, Any]) -> str: paragraphs = [clean_text(item) for item in article.get("paragraphs", []) if clean_text(item)] core_view = "\n".join(paragraphs[:2]) if paragraphs else "这是一篇从公众号文章采集后生成的再创作 brief。" background = [truncate_text(item, 80) for item in paragraphs[1:4]] or [truncate_text(core_view, 80)] arguments = infer_arguments(article) materials = [ f"来源链接:{article['source_url']}", f"来源公众号/作者:{article.get('author') or '未识别'}", ] materials.extend(truncate_text(item, 90) for item in paragraphs[:3]) lines = [ f"# 阶段 2 采集 Brief:{article['title']}", "", "## 基础信息", "", f"- `date`:{article['publish_date']}", f"- `slug`:{article['slug']}", f"- `topic`:{article['title']}", "- `target_reader`:关注原文主题、希望将公众号素材加工为可发布观点文章的读者", f"- `publish_goal`:基于公众号素材再创作一篇适合公众号发布的观点型长文,保留原文有价值的信息点,但不直接照抄原文", "", "## 核心观点", "", core_view, "", "## 背景与语境", "", *[f"- {item}" for item in background[:4]], "", "## 论证方向", "", *[f"{index}. {item}" for index, item in enumerate(argumen ...[truncated 2454 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill describes reading an input file and writing both a generated brief and a raw HTML archive, but it does not declare any explicit tool scope such as permissions or allowed-tools. That creates an authorization gap where the runtime may grant broader filesystem access than the skill actually needs, increasing the risk of unintended file reads/writes if the implementation is modified, compromised, or misused. In this context, the skill processes externally supplied URLs and writes artifacts to the repository, so constraining file access is important for limiting blast radius.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Several default prompts and all generated markdown section headings and style requirements are fixed in Chinese, which effectively forces a specific language/locale in the skill's natural-language output. The file does not indicate that this is optional, user-selected, or justified as a documented region-specific constraint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This code fetches remote article HTML from a URL, may launch a browser-based retrieval flow, and then writes both a generated markdown brief and the raw HTML archive to disk. There is no confirmation prompt, logging/print statement, or comment/docstring in this file warning the user that remote content will be retrieved and stored locally.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This manifest file describes the skill's behavior in general terms but does not specify any narrow activation conditions, allowed trigger phrases, or exclusion conditions. In a manifest context, the lack of specificity can make invocation matching overly broad for requests involving WeChat articles or summarization.

Content

No source excerpt is available for this finding.