Back to skill

Security audit

微信公众号文章抓取

Security checks for vulnerabilities and agentic risk

Overview

This WeChat article-fetching skill is mostly straightforward, but its script can fetch any HTTP or HTTPS URL, not just WeChat links.

Review before installing. Use this only in a sandbox or environment with restricted network egress unless the script is changed to allow only mp.weixin.qq.com, block private and metadata addresses, and validate redirects. Pin and review the Python dependencies for reproducible installs.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/weixin_fetch.py:39
Finding

Unrestricted URL Fetching Enables Server-Side Request Forgery

Content
View full analysis

Vulnerability Details

File Location: scripts/weixin_fetch.py, lines 39–49 and 136–142
Vulnerability Type: Server-Side Request Forgery (SSRF) caused by insufficient URL and redirect validation
Risk Level: High

Vulnerable Code

python
def validate_url(url: str) -> Tuple[bool, str]:
    """Validate URL: must be http(s) with valid domain."""
    try:
        p = urlparse(url)
        if p.scheme not in ('http', 'https'):
            return False, f"Only http/https allowed, got '{p.scheme or 'none'}'"
        if not p.netloc:
            return False, "Missing domain"
        return True, ""
    except Exception as e:
        return False, str(e)
python
with httpx.Client(
    follow_redirects=True,
    max_redirects=MAX_REDIRECTS,
    timeout=30.0
) as client:
    response = client.get(url, headers=headers)
    response.raise_for_status()

Technical Analysis

Although the skill is documented as a specialized fetcher for mp.weixin.qq.com, validate_url() only verifies that the URL uses HTTP or HTTPS and contains a network location. It does not enforce the documented WeChat hostname.

Consequently, attacker-controlled URLs targeting loopback addresses, link-local addresses, private network ranges, or other services reachable from the host are accepted. Examples include local web services, private administrative interfaces, and cloud instance metadata endpoints.

The HTTP client is also configured with follow_redirects=True. Even if validation of the initial hostname were added independently, a permitted public URL could redirect to an internal destination unless every redirect target is separately validated.

The implementation additionally lacks protection against:

  • IPv4 and IPv6 loopback addresses.
  • Private, link-local, reserved, unspecified, and multicast addresses.
  • DNS records resolving a public hostname to a prohibited address.
  • DNS rebinding o ...[truncated 2262 chars]
Remediation
View remediation

Remediation Suggestions

  1. Enforce the intended hostname allowlist

    • Normalize the hostname using IDNA rules.
    • Require an exact match for mp.weixin.qq.com, or use a narrowly defined list of approved WeChat hosts.
    • Do not use suffix checks that could accept domains such as mp.weixin.qq.com.attacker.example.
    • Reject URLs containing embedded user-information.
  2. Validate resolved addresses

    • Resolve all destination hostnames before making a request.
    • Reject IPv4 and IPv6 loopback, private, link-local, reserved, multicast, and unspecified addresses.
    • Validate every resolved address rather than accepting a hostname when only one result appears safe.
    • Where supported, verify the actual connected peer address to reduce DNS-rebinding and time-of-check/time-of-use risks.
  3. Secure redirect processing

    • Disable automatic redirects with follow_redirects=False.
    • Process redirects manually.
    • Normalize and validate every Location destination using the same hostname and IP restrictions before following it.
    • Apply a strict redirect count limit.
  4. Limit response resource consumption

    • Stream response data instead of loading the entire response body through response.text.
    • Enforce a maximum byte count while reading.
    • Reject unexpectedly large Content-Length values and stop streaming once the configured limit is reached.
    • Consider restricting accepted content types to expected HTML media types.
  5. Apply network-level defense in depth

    • Run the skill in a restricted environment with egress access limited to approved WeChat endpoints.
    • Block access to loopback, private networks, and cloud metadata services at the firewall or sandbox layer.
    • Avoid relying exclusively on application-level URL validation.
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (9)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill explicitly performs outbound network access to fetch remote WeChat content, but the manifest declares no tool scope or permission boundary for that capability. This creates a governance and containment gap: an agent or reviewer cannot tell from the skill declaration that it can make arbitrary web requests, increasing the risk of unintended data exfiltration, SSRF-like misuse through crafted URLs, or use in contexts where network access should be denied.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The validator only checks that the input uses HTTP or HTTPS and has a domain; it does not enforce the advertised mp.weixin.qq.com scope. In an agent-skill context, this turns a supposedly narrow WeChat extractor into a general outbound fetch primitive, which can be abused to access arbitrary external endpoints, including internal or sensitive network resources if the agent runs in a trusted environment.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The fetch logic performs an unrestricted GET on any validated HTTP(S) URL and follows redirects, so the implementation materially exceeds its stated WeChat-only purpose. In practice this broadens the skill into a generic web retrieval tool, increasing SSRF-style risk and enabling misuse as a network access proxy from the agent runtime.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency specification uses a lower-bound only constraint (httpx>=0.20.0), which allows future installs to resolve to different versions over time. This weakens build reproducibility and can unintentionally introduce vulnerable or breaking releases into the skill's runtime environment.

Content

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

text
httpx>=0.20.0
readability-lxml>=0.8.1
lxml>=4.0.0

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

The manifest does not pin httpx, and known advisories exist for some httpx versions, so the actual deployed package may be vulnerable depending on resolution time. In a network-fetching skill, using an unverifiable HTTP client version increases uncertainty around request-handling security and makes risk assessment impossible.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

readability-lxml>=0.8.1 is unpinned, so deployments may install different versions depending on timing and resolver behavior. That creates supply-chain and reproducibility risk because a later compromised or vulnerable release could be pulled in without code changes.

Content

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

text
httpx>=0.20.0
readability-lxml>=0.8.1
lxml>=4.0.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

lxml>=4.0.0 permits a wide range of versions, including potentially outdated or future releases with security issues. For a skill that fetches and parses untrusted web content, parser-library version control matters more because parsing bugs can be reachable from attacker-controlled input.

Content

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

text
httpx>=0.20.0
readability-lxml>=0.8.1
lxml>=4.0.0

Unverifiable Dependency: lxml has 14 known advisory(ies) (CVE-2021-43818 (lxml's HTML Cleaner allows crafted and SVG embedded scripts to pass through); CVE-2014-3146 (lxml Cross-site Scripting Via Control Characters); CVE-2021-28957 (lxml vulnerable to Cross-Site Scripting ) +11 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
93% confidence
Finding

lxml has multiple historical advisories, and the unpinned requirement prevents verification that a safe version will be installed. Because this skill processes remote HTML from WeChat pages, parser or sanitizer flaws in lxml are more relevant than in many contexts and could expose consumers to malicious document-handling issues.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The request headers hard-code "Accept-Language" to prefer Chinese locales, which imposes a language/locale preference in the skill's behavior. The file does not offer user opt-in or configuration for this locale choice, and no region-specific policy justification is documented in the code.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.