Back to skill

Security audit

Wechat Look

Security checks for vulnerabilities and agentic risk

Overview

This skill is meant to read WeChat articles with OCR, but its network fetching is broader than that purpose and can be abused to request arbitrary/internal URLs or consume excessive resources.

Review before installing. Use this only in an environment where outbound requests are contained, and avoid processing untrusted or attacker-provided URLs until the skill enforces HTTPS mp.weixin.qq.com article URLs, validates image CDN destinations, blocks private/internal addresses and redirects, and limits image count, download size, and OCR runtime.

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
wechat_reader_ocr.py:163
Finding

Server-Side Request Forgery Through Unrestricted Article URL

Content
View full analysis
str: """Normalize a WeChat article URL.""" if not re.match(self.base_url_pattern, url): return url ``` ```python def read_article(self, original_url: str) -> Dict[str, Any]: try: # Normalize URL normalized_url = self.normalize_url(original_url) # Retrieve and parse the page using requests try: resp = requests.get(normalized_url, timeout=15, headers={ 'User-Agent': 'Mozilla/5.0 (compatible; wechat-look/1.0)' }) resp.raise_for_status() html = resp.text ``` ### Technical Analysis The implementation defines a regular expression intended to recognize WeChat article URLs. However, `normalize_url()` does not reject a URL that fails this check. Instead, it returns the untrusted URL unchanged. `read_article()` subsequently passes that returned value directly to `requests.get()`. Consequently, the documented restriction to WeChat article URLs is not enforced at the network boundary. An attacker can supply an arbitrary URL using HTTP or HTTPS, including URLs resolving to: - Loopback services such as `127.0.0.1` or `::1` - Private network services - Link-local services - Cloud instance metadata endpoints - Internal administrative interfaces - Other services reachable only from the Skill host The implementation also uses the default redirect behavior of `requests`, so an initially acceptable-looking endpoint could redirect the request to an internal destination unless every redirect target is independently validated. ### Attack Path 1. An attacker invokes the Skill with a URL such as `http://127.0.0.1:8080/`, a private-network address, or a cloud metadata end ...[truncated 1219 chars]
Remediation
View remediation
None: parsed = urlparse(url) if parsed.scheme != "https": raise ValueError("Only HTTPS URLs are permitted") if parsed.hostname != "mp.weixin.qq.com": raise ValueError("Only mp.weixin.qq.com URLs are permitted") if not parsed.path.startswith("/s/"): raise ValueError("Unsupported WeChat article path") if parsed.username or parsed.password: raise ValueError("URL credentials are not permitted") for entry in getaddrinfo(parsed.hostname, 443): address = ip_address(entry[4][0]) if ( address.is_private or address.is_loopback or address.is_link_local or address.is_multicast or address.is_reserved or address.is_unspecified ): raise ValueError("The destination resolves to a prohibited address") ``` DNS resolution checks should be combined with redirect validation and network-level egress controls to reduce DNS re ...[truncated 50 chars]

T09 · Insecure Skill Coding Practices

Error
Location
wechat_reader_ocr.py:40
Finding

Second-Stage SSRF and Resource Exhaustion Through Article-Controlled Image URLs

Content
View full analysis
List[str]: """Extract all image URLs from HTML.""" image_urls = [] # Extract the src attribute from img elements img_pattern = r']*src=["\']([^"\']+)["\']' matches = re.findall(img_pattern, html_content, re.I) for url in matches: if url.startswith('http'): image_urls.append(url) elif url.startswith('//'): image_urls.append('https:' + url) ``` Each accepted URL is passed to a Node.js subprocess: ```python def ocr_image_via_node(self, image_url: str) -> str: """Process an image with the Node.js OCR script.""" script_path = Path(__file__).parent / "ocr_node" / "ocr_chinese.js" try: result = subprocess.run( ["node", str(script_path), image_url], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=60, ) if result.returncode == 0: data = json.loads(result.stdout) return data.get("text", "").strip() ``` There is no limit on the number of extracted images: ```python # Perform OCR by invoking the Node OCR implementation if image_urls: ocr_texts = [] for idx, img_url in enumerate(image_urls, start=1): txt = self.ocr_image_via_node(img_url) if txt: ocr_texts.append(f"[Image {idx}] {txt}") result['ocr_text'] = "\n".join(ocr_texts) ``` The Node.js downloader accepts the URL and buffers the complete response without a byte limit: ```javascript async function downloadImage ...[truncated 3887 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (42)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

A claim of article retrieval and OCR support while the implementation returns mock results or lacks OCR calls is a material misrepresentation. In this context, the primary danger is deceptive behavior and broken security assumptions, not necessarily an exploit primitive by itself.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

A claim of article retrieval and OCR support while the implementation returns mock results or lacks OCR calls is a material misrepresentation. In this context, the primary danger is deceptive behavior and broken security assumptions, not necessarily an exploit primitive by itself.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

A claim of article retrieval and OCR support while the implementation returns mock results or lacks OCR calls is a material misrepresentation. In this context, the primary danger is deceptive behavior and broken security assumptions, not necessarily an exploit primitive by itself.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

A claim of article retrieval and OCR support while the implementation returns mock results or lacks OCR calls is a material misrepresentation. In this context, the primary danger is deceptive behavior and broken security assumptions, not necessarily an exploit primitive by itself.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

A claim of article retrieval and OCR support while the implementation returns mock results or lacks OCR calls is a material misrepresentation. In this context, the primary danger is deceptive behavior and broken security assumptions, not necessarily an exploit primitive by itself.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

A claim of article retrieval and OCR support while the implementation returns mock results or lacks OCR calls is a material misrepresentation. In this context, the primary danger is deceptive behavior and broken security assumptions, not necessarily an exploit primitive by itself.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

A claim of article retrieval and OCR support while the implementation returns mock results or lacks OCR calls is a material misrepresentation. In this context, the primary danger is deceptive behavior and broken security assumptions, not necessarily an exploit primitive by itself.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

A claim of article retrieval and OCR support while the implementation returns mock results or lacks OCR calls is a material misrepresentation. In this context, the primary danger is deceptive behavior and broken security assumptions, not necessarily an exploit primitive by itself.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

A claim of article retrieval and OCR support while the implementation returns mock results or lacks OCR calls is a material misrepresentation. In this context, the primary danger is deceptive behavior and broken security assumptions, not necessarily an exploit primitive by itself.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

A claim of article retrieval and OCR support while the implementation returns mock results or lacks OCR calls is a material misrepresentation. In this context, the primary danger is deceptive behavior and broken security assumptions, not necessarily an exploit primitive by itself.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

A claim of article retrieval and OCR support while the implementation returns mock results or lacks OCR calls is a material misrepresentation. In this context, the primary danger is deceptive behavior and broken security assumptions, not necessarily an exploit primitive by itself.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The example invocation is a natural-language phrase a user might commonly say in conversation, so it can cause unintended skill activation or routing when the user did not explicitly intend to invoke this skill. In a skill that fetches external web content, accidental triggering can lead to unplanned network access and processing of untrusted remote content.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill documentation declares capabilities that require outbound network access and subprocess execution, but it does not declare any explicit tool scope or permissions. This weakens reviewability and policy enforcement because a consumer cannot easily see that the skill may fetch remote content and launch local commands.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The description states this is a dedicated tool for reading WeChat public account articles, entirely in Chinese, and the usage example is also Chinese-only. There is no explicit user opt-in, language choice, or justification that the skill is intentionally restricted to Chinese-speaking users as a locale-specific compliance tool.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 32)May include surrounding context.

  1. 安装系统依赖:
    bash
    # Ubuntu/Debian
    sudo apt install python3 nodejs npm
    
    # macOS
    brew install python node
    

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code's natural-language status and error messages are hard-coded in Chinese (for example, completion and failure messages), with no option to choose locale. This can violate organizational language/locale policy because the skill forces one language for user-visible output rather than offering opt-in or configuration.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Comments, error text, progress messages, and usage guidance are presented in Chinese, while the tool does not provide any user opt-in or locale selection for these user-facing outputs. The policy allows locale constraints only when clearly documented and justified, which is not evident here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code presents its description, status messages, errors, and usage text in Chinese, and it is explicitly tailored to Chinese/English OCR without any user opt-in for language or locale. That creates a natural-language policy concern because the skill effectively forces a specific language experience rather than allowing user choice or clearly justifying the locale restriction.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest says the skill recognizes Chinese and English text in images, but the implementation explicitly restricts OCR to the English language model only. This means the actual behavior is narrower than the advertised capability and can fail to satisfy the stated purpose for Chinese text extraction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code explicitly restricts OCR to the 'eng' language pack, and comments state that only English is used. This is a natural-language/locale policy concern because the skill hard-codes a language choice without any user opt-in or configurable alternative.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code fetches a user-supplied image URL over the network, which transmits request metadata and potentially user-provided data to a remote host. Although there is progress logging, there is no explicit warning or comment disclosing the network/privacy implication of downloading external content.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Several user-visible strings are in Chinese, including the file description and runtime error/usage messages, but the script does not provide any user opt-in or alternative locale. This can violate language/locale policy when a skill forces a specific language experience by default.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script fetches an arbitrary user-supplied image URL directly, which enables server-side requests to external hosts without validation or restriction. In an agent or service context, this can expose internal network resources to SSRF-style probing, leak the tool's IP/user-agent to third parties, and retrieve unexpected content from attacker-controlled endpoints.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code file contains user-facing natural-language strings such as the module description, test labels, and success/failure messages entirely in Chinese. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified, which is not present here.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · test_ocr.py (reported line 36)May include surrounding context.

python
try:
            # 执行OCR
            result = subprocess.run(
                ["node", str(ocr_script), image_url],
                capture_output=True,
                text=True,