Back to skill

Security audit

wechat-article

Security checks for vulnerabilities and agentic risk

Overview

This skill is a WeChat article fetcher, but its weak URL checks can let a crafted input make network requests to unintended internal or private addresses.

Review this skill before installing or using it in any environment with access to private networks, cloud metadata services, intranet apps, or sensitive URLs. Use only trusted WeChat article URLs, and prefer an update that parses and allowlists the exact mp.weixin.qq.com hostname, blocks redirects to private addresses, and clearly discloses r.jina.ai data sharing.

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/wechat_article.py:169
Finding

Weak URL Validation Enables Server-Side Request Forgery

Content
View full analysis

Vulnerability Details

File Location: scripts/wechat_article.py:56-69, 169-191
Vulnerability Type: Server-Side Request Forgery through insufficient URL validation
Risk Level: High

Vulnerable Code

python
def fetch_via_web_fetch(url: str) -> dict:
    """
    Directly fetch webpage content.
    """
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
    }

    try:
        response = requests.get(url, headers=headers, timeout=30)
        response.raise_for_status()
        html = response.text
python
def wechat_article(url: str) -> dict:
    """
    Main function for retrieving a WeChat article.
    """
    # Validate URL
    if not url or "mp.weixin.qq.com" not in url:
        return {
            "success": False,
            "error": "Invalid WeChat article URL"
        }

    # Strategy 1: Use jina.ai
    result = fetch_via_jina(url)
    if result["success"]:
        parsed = parse_jina_content(result["content"])
        return {
            "success": True,
            "method": result["method"],
            "title": parsed["title"],
            "content": parsed["content"],
            "publish_time": parsed["publish_time"],
            "account": parsed["account"],
            "url": url
        }

    # Strategy 2: Fetch directly
    result = fetch_via_web_fetch(url)

Technical Analysis

The application validates an untrusted URL by checking only whether the literal substring mp.weixin.qq.com appears anywhere in the supplied value. This does not establish that the parsed destination hostname is actually mp.weixin.qq.com.

An attacker can place the trusted hostname in an irrelevant URL component, such as the user-information section or query string. For exa ...[truncated 2541 chars]

Remediation
View remediation

Remediation Suggestions

  1. Parse the URL with urllib.parse.urlsplit() and reject malformed URLs.
  2. Require the https scheme.
  3. Compare the normalized parsed hostname against an explicit allowlist. Require exactly mp.weixin.qq.com, or explicitly enumerate any approved subdomains instead of using substring or suffix matching.
  4. Reject URLs containing user information, unexpected ports, fragments, or ambiguous host encodings.
  5. Resolve the hostname before making a request and reject every address that is loopback, private, link-local, reserved, multicast, or unspecified using Python's ipaddress module.
  6. Protect against DNS rebinding by ensuring the validated address is the address used for the connection.
  7. Disable automatic redirects with allow_redirects=False, or manually process redirects and apply the complete validation procedure to every destination.
  8. Apply the same validation before sending a URL to the third-party Jina service.
  9. Enforce response-size and content-type limits to reduce the impact of malicious or unexpectedly large responses.
  10. Add regression tests covering user-information URLs, query-string bypasses, encoded hostnames, IPv4 and IPv6 loopback addresses, private ranges, link-local metadata addresses, alternate ports, and redirect chains.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill explicitly performs network-backed content retrieval but does not declare any tool scope such as permissions or allowed-tools. That omission can cause operators or downstream systems to underestimate what the skill can access, weakening policy enforcement and increasing the chance of unintended outbound requests.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill recommends using r.jina.ai, a third-party extraction service, without warning that article URLs and possibly retrieved content will be transmitted to an external provider. This creates privacy, confidentiality, and compliance risk, especially if users process non-public or sensitive links while assuming extraction is local or first-party.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The file-level description states the tool is for WeChat public-account articles and all user-facing strings, usage text, and extracted metadata labels are hard-coded in Chinese. This imposes a language/locale constraint without any opt-in or documented justification that the skill is intentionally limited to Chinese-speaking users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The skill's natural-language description, headings, usage notes, and warnings are entirely in Chinese, with no indication that another language is available. This can constitute a language policy issue when a skill forces a specific language without user opt-in or an explicitly documented locale constraint.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.