Back to skill

Security audit

Article Extract

Security checks for vulnerabilities and agentic risk

Overview

This skill is a simple article extractor, but it advertises anti-scraping bypass and fetches arbitrary user-supplied URLs without safeguards.

Install only if you intentionally need a Chinese/WeChat-oriented article extractor and are prepared to control which URLs it can fetch. Do not let it process untrusted, model-suggested, file://, localhost, private-network, or metadata-service URLs, and consider adding allowlists and HTTP/HTTPS-only validation before use.

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/extract.py:36
Finding

Unrestricted URL Fetching Enables SSRF and Local File Disclosure

Content
View full analysis

Vulnerability Details

File Location: scripts/extract.py, lines 36–45 and 77–80
Vulnerability Type: Server-Side Request Forgery (SSRF) and unrestricted URI scheme access
Risk Level: High

Vulnerable Code

python
def fetch_url(url):
    """抓取网页内容"""
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
    }
    req = urllib.request.Request(url, headers=headers)
    
    try:
        with urllib.request.urlopen(req, timeout=30) as response:
            return response.read().decode('utf-8', errors='ignore')
    except Exception as e:
        print(f"Error fetching URL: {e}", file=sys.stderr)
        return None

The untrusted value originates in main():

python
url = sys.argv[1]

print(f"Fetching: {url}", file=sys.stderr)
html = fetch_url(url)

Technical Analysis

A URL supplied through the command line is passed directly to urllib.request.Request and urllib.request.urlopen without validation of its scheme, hostname, resolved IP address, port, or redirect destination.

This creates an SSRF primitive because the request executes with the process's network access rather than the caller's access. An attacker can submit URLs targeting loopback interfaces, private networks, link-local addresses, internal services, or cloud instance metadata endpoints. DNS-based checks would also be insufficient unless the resolved address used for the connection is validated against prohibited address ranges.

The implementation does not restrict input to HTTP and HTTPS. Python's urllib can handle additional URI schemes, including file://, allowing files readable by the process to be opened and returned. HTTP redirects are followed by default, so validating only the initial URL would not prevent a public endpoint from redirecting to a prohibited local or internal destination.

The retrieved response is decoded, processed as text, ...[truncated 1493 chars]

Remediation
View remediation

Remediation Suggestions

  1. Parse URLs with urllib.parse.urlsplit and permit only explicit http and https schemes.
  2. Reject URLs containing embedded credentials, malformed hostnames, fragments where inappropriate, or ports outside an approved set.
  3. Resolve the hostname before connecting and reject every address that is loopback, private, link-local, multicast, reserved, or unspecified, for both IPv4 and IPv6.
  4. Explicitly block cloud metadata destinations and equivalent metadata hostnames. Do not rely solely on hostname deny lists.
  5. Disable automatic redirects or implement a redirect handler that repeats all scheme, hostname, port, DNS, and IP-range checks for every redirect destination.
  6. Mitigate DNS rebinding by ensuring the validated address is the address used for the connection, or by routing requests through a controlled outbound proxy with equivalent restrictions.
  7. Apply response-size and redirect-count limits to reduce memory exhaustion and denial-of-service risk.
  8. Enforce outbound network policy at the operating-system, container, or proxy layer so the process cannot reach private networks or metadata services even if application validation is bypassed.
  9. Add regression tests covering file:// inputs, loopback and private IPv4/IPv6 addresses, encoded IP representations, metadata endpoints, DNS rebinding scenarios, and redirects to prohibited destinations.
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 (6)

Natural-Language Policy Violations

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill description explicitly states that it is intended to bypass anti-scraping protections, which signals an attempt to evade site access controls rather than simply parse publicly available content. Evasion-oriented behavior materially increases legal, policy, and abuse risk, especially when paired with arbitrary URL fetching.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

Advertising bypass of WeChat anti-scraping protections is a specific claim of defeating a platform's defensive controls. In this context, the skill is more dangerous because it targets known anti-abuse mechanisms on a major platform, suggesting purpose-built evasion rather than benign extraction.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill performs outbound network access to arbitrary user-supplied URLs, but the manifest does not declare any tool scope or permissions to make that capability explicit. This weakens reviewability and user consent, and can enable unintended use as a generic web fetcher, including access to attacker-chosen endpoints.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The natural-language description and inline documentation are entirely in Chinese, with no indication that language choice is optional or that the skill is intentionally region-specific. Under the stated policy, forcing a specific language without user opt-in can be a locale/language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The documentation omits a clear warning that the skill will make outbound HTTP requests to arbitrary URLs provided by the user. Without that notice, users and reviewers may underestimate privacy, compliance, or SSRF-like risks arising from fetching untrusted destinations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This code performs an HTTP request to an arbitrary URL provided by the user, which transmits the user's network metadata and target URL to a remote server. While the script logs that it is fetching the URL, it does not disclose any privacy or external-network implications in comments or documentation visible in this file.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.