Back to skill

Security audit

Wechat Mp To Notion

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but its script can fetch any user-supplied URL and upload parsed content to Notion, which is broader than the stated WeChat-only purpose.

Review before installing. Only use this with trusted WeChat article URLs and a Notion integration limited to the minimum pages or databases needed. The publisher should add strict URL validation for https://mp.weixin.qq.com/s/ links, reject redirects to other hosts or private addresses, document the Notion data transfer, and ideally ask for confirmation before saving.

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/save_wechat_mp_to_notion.py:27
Finding

Unrestricted Source URL Enables Server-Side Request Forgery and Content Exfiltration

Content
View full analysis
str: req = urllib.request.Request(url, headers={"User-Agent": UA}) with urllib.request.urlopen(req, timeout=30) as resp: return resp.read().decode("utf-8", "ignore") ``` The unrestricted argument is passed to `fetch()`, and extracted content is subsequently uploaded to Notion: ```python ap.add_argument("wechat_url") ap.add_argument("notion_parent_id") ap.add_argument("--parent-type", choices=["page", "database"], default="page") args = ap.parse_args() html_data = fetch(args.wechat_url) title, author, publish_date = extract_metadata(html_data) content_items = parse_article(html_data) page = create_page( args.notion_parent_id, args.parent_type, title, author, publish_date, args.wechat_url ) append_blocks(page["id"], content_items) ``` ### Technical Analysis The Skill documentation declares that the source should be a public WeChat article at `https://mp.weixin.qq.com/s/...`. However, the script does not enforce that restriction. It accepts any string as `wechat_url` and passes it directly to `urllib.request.urlopen()`. The implementation does not validate: - The URL scheme. - The normalized hostname. - The expected `/s/` path. - Embedded credentials or nonstandard ports. - DNS resolution to loopback, private, link-local, or reserved addresses. - The destinations of HTTP redirects. Consequently, a caller may direct the runtime to services that are not part of the declared functionality, including localhost endpoints, private-network services, cloud metadata endpoints, or other URLs accessible from the host. After fetching the response, the script parses it and sends extracted metadata and article blocks to the fixed Notion API. Responses containing a recognized `js_co ...[truncated 2577 chars]
Remediation
View remediation
str: parsed = urlsplit(url) if parsed.scheme != "https": raise ValueError("Only HTTPS WeChat article URLs are allowed") if parsed.username or parsed.password: raise ValueError("URL credentials are not allowed") if (parsed.hostname or "").lower() != "mp.weixin.qq.com": raise ValueError("Only mp.weixin.qq.com is allowed") if parsed.port not in (None, 443): raise ValueError("Nonstandard ports are not allowed") if not parsed.path.startswith("/s/"): raise ValueError("URL is not a supported WeChat article path") for result in socket.getaddrinfo(parsed.hostname, 443): address = ipaddress.ip_address(result[4] ...[truncated 560 chars]
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 (5)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill invokes a Python script that uses network access to fetch WeChat content and relies on an environment secret (NOTION_API_KEY), but the skill file does not declare any tool scope or permissions boundaries. This creates an authorization and transparency gap: the agent may run capability-bearing code without explicit declaration, making review and policy enforcement harder and increasing the chance of unintended external access or secret use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill description explains that it fetches article HTML and creates Notion pages, but it does not clearly warn that article content, metadata, and possibly embedded external image URLs will be transmitted to third-party services and persisted in Notion. This is dangerous because users may trigger the skill without understanding the data flow, leading to unintended disclosure, storage of copyrighted or sensitive content, and privacy/compliance issues.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/save_wechat_mp_to_notion.py (reported line 199)May include surrounding context.

python
{"object": "block", "type": "paragraph", "paragraph": {"rich_text": [text_obj(f"Source: {source_url}")]}}
            ]
        }
    return notion_request("POST", "https://api.notion.com/v1/pages", payload)


def append_blocks(page_id, items):

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/save_wechat_mp_to_notion.py (reported line 206)May include surrounding context.

python
{"object": "block", "type": "paragraph", "paragraph": {"rich_text": [text_obj(f"Source: {source_url}")]}}
            ]
        }
    return notion_request("POST", "https://api.notion.com/v1/pages", payload)


def append_blocks(page_id, items):

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This script fetches content from a user-supplied WeChat URL and then sends extracted article data to the Notion API, but it provides no confirmation prompt, warning message, or explanatory comment/docstring about these outbound network operations. Because the script transmits article content and metadata to external services, users are not explicitly informed at execution time about the privacy-relevant data flow.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.