Back to skill

Security audit

wechat-article-skill

Security checks for vulnerabilities and agentic risk

Overview

The skill is clearly meant to fetch WeChat articles, but its script can fetch arbitrary URLs and lacks bounded response handling, so users should review it before installing.

Install only if you are comfortable with a skill that performs outbound web requests. Use it only with intended WeChat article links, and prefer a version that validates mp.weixin.qq.com/s URLs, blocks private/local destinations and unsafe redirects, caps response size, and pins 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

Error
Location
scripts/get_content.py:53
Finding

Unrestricted URL Fetching Enables Server-Side Request Forgery

Content
View full analysis
tuple[str, int | None]: """ 请求公众号链接,返回 (html, status_code)。 status_code 为 None 表示非 HTTP 错误(如连接失败)。 """ req = Request( url, headers={ "User-Agent": user_agent, "Accept": "text/html,application/xhtml+xml", "Accept-Language": "zh-CN,zh;q=0.9", }, method="GET", ) resp = urlopen(req, timeout=TIMEOUT, context=_SSL_CTX) html = resp.read().decode(resp.headers.get_content_charset() or "utf-8") return html, resp.status if hasattr(resp, "status") else 200 ``` The unvalidated value originates from the command-line argument: ```python parser.add_argument( "--url", required=True, help="公众号文章链接,如 https://mp.weixin.qq.com/s/xxx", ) ``` ### Technical Analysis The documentation describes the input as a WeChat article URL under `https://mp.weixin.qq.com/s/`, but the implementation does not enforce this restriction. The supplied URL is passed directly to `urllib.request.urlopen`. There is no validation of: - The URL scheme - The normalized hostname - The expected `/s/` path - Embedded credentials - The destination port - The resolved destination IP address - Redirect destinations Because `urlopen` follows HTTP redirects, validating only an initial URL in future changes would also be insufficient unless every redirect target is checked. An attacker can cause the process to send requests to localhost, private network addresses, link-local services, or cloud metadata endpoints. The script only prints a response when it contains an element matching `#page-content`, which limits direct disclosure for some targets. However, internal HTML applications containing that identifier can ...[truncated 1348 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/get_content.py:64
Finding

Unbounded Response Buffering Can Exhaust Process Memory

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unpinned Dependency Versions Permit Unreviewed Package Updates

Content
View full analysis
=4.12.0 certifi>=2024.0.0 ``` The documented installation command is: ```bash pip install -r requirements.txt ``` ### Technical Analysis Both dependencies use open-ended minimum-version constraints. Consequently, installations performed at different times can retrieve materially different package versions without a corresponding review or source change in this project. No package hashes are specified, so the installer does not verify artifacts against project-approved cryptographic digests. The package names themselves appear to be ordinary PyPI dependency names; the audit found no evidence of typosquatting, dependency confusion, or a malicious custom package source. The risk arises from uncontrolled future updates and lack of reproducibility rather than from a known malicious dependency. ### Attack Path 1. A future compromised, malicious, or incompatible package version is published under one of the allowed package names. 2. The version satisfies the open-ended `>=` constraint. 3. A user runs `pip install -r requirements.txt`. 4. The installer retrieves the newer artifact without project-specific hash verification. 5. Package installation or later import executes the affected dependency code in the user's Python environment. This exploitation path depends on a future upstream compromise, malicious release, or registry/account security failure; none was observed in the audited files. ### Impact Assessment A compromised dependency would execute with the privileges of the user installing or running the Skill. Depending on those privileges, it could access local files, environment variables, network resources, and Agent data. The current files do not demonstrate an active dependency compromise. The immediate impact is reduced build ...[truncated 93 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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 (9)

Natural-Language Policy Violations

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The description states the skill processes WeChat article links and all instructions are written as if interaction is exclusively in Chinese, without indicating that language selection is optional. Under the stated policy, forcing a specific language or locale without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill clearly directs the agent to perform outbound network access to fetch third-party WeChat content, yet it declares no explicit tool scope or permissions. This creates a least-privilege and transparency problem: the agent may use network/browser capabilities without an explicit contract, increasing the risk of unintended external requests and harder security review.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs the agent to fetch user-supplied URLs from a third-party service and even use a browser fallback, but it does not disclose that the requested URL and associated metadata will be sent to WeChat. This can expose user interests, identifiers, IP/browser fingerprints, and browsing context to an external party without informed consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file documents a tool that retrieves HTML from mp.weixin.qq.com, which is a network operation covered by the missing-warning category for markdown files. While the usage is clear, the description does not explicitly warn that running the tool will make an external HTTP request to a third-party service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The natural-language content of the skill is entirely in Chinese, and the file does not offer an alternative language or indicate that the skill is intentionally limited to Chinese-speaking users. Under the stated policy, forcing a specific language without user opt-in is a reportable locale-policy issue.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
91% confidence
Finding

The dependency is specified with a lower bound only, which allows future versions to be installed without review and makes builds non-reproducible. This increases supply-chain risk because a newly released vulnerable or breaking version of beautifulsoup4 could be pulled into the skill unexpectedly.

Content

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

text
beautifulsoup4>=4.12.0
certifi>=2024.0.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The certifi package is also unpinned, so installation may resolve to different versions over time. In a network-facing skill that fetches remote web content, uncontrolled CA bundle changes can affect TLS trust behavior and may expose the deployment to known-bad or unreviewed dependency versions.

Content

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

text
beautifulsoup4>=4.12.0
certifi>=2024.0.0

Unverifiable Dependency: certifi has 6 known advisory(ies) (CVE-2024-39689 (Certifi removes GLOBALTRUST root certificate); CVE-2022-23491 (Certifi removing TrustCor root certificate); CVE-2023-37920 (Removal of e-Tugra root certificate) +3 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
82% confidence
Finding

The manifest does not pin certifi, and certifi has had security-relevant CA trust store advisories in past releases, so it is not possible to verify whether a safe version will be installed. Because this skill retrieves remote WeChat article content over HTTPS, certificate trust decisions are directly relevant to secure transport and endpoint validation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The Accept-Language header is hard-coded to "zh-CN,zh;q=0.9", which imposes a specific language/locale preference on every request. Under the policy, locale constraints should be optional or clearly justified; this file does not offer user opt-in or explain why forcing Chinese locale is required.

Content

No source excerpt is available for this finding.