Back to skill

Security audit

Wechat Report

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly aligned with WeChat article report generation, but it has under-scoped network and browser automation that could access arbitrary URLs and reuse a persistent browser session.

Review before installing. Use this only in a sandboxed workspace, do not run it on untrusted request Markdown or unreviewed seed URLs, and avoid logging into accounts through its Playwright profile unless you are comfortable with that session being reused under .cache/wechat-report-playwright. Prefer a version that enforces mp.weixin.qq.com URL allowlisting, validates redirects, uses a temporary browser profile by default, and ships pinned dependency lockfiles.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
runtime.py:273
Finding

Unvalidated Seed URLs Allow Server-Side Request Forgery and Excessive Browser Access

Content
View full analysis
= request["max_articles"]: break try: probe = fetch_page(url, timeout=20) access_meta = classify_page( source_url=url, html_text=probe["html"], final_url=probe["final_url"], ) ``` It may also be passed to a persistent Playwright browser context: ```python browser_engagement: dict[str, Any] | None = None public_engagement = extraction["data"].get("engagement") or {} if request["collect_engagement"] and not public_engagement.get("metrics_visible_in_public_html"): try: browser_engagement = run_node_script( engagement_script, str(workspace_root), url, str(browser_profile_dir), cwd=workspace_root, ) ``` ```javascript const [, , workspaceRoot, sourceUrl, profileDir] = process.argv; if (!workspaceRoot || !sourceUrl || !profileDir) { throw new Error('Usage: node collect_engagement.js '); } const playwright = resolvePlaywright(workspaceRoot); if (!playwright) { throw new Error('Playwright dependency not found. Install playwright or reuse ...[truncated 3427 chars]
Remediation
View remediation
str: normalized = canonicalize_url(value) parsed = urllib.parse.urlparse(normalized) if parsed.scheme != "https": raise ValueError("Only HTTPS WeChat article URLs are permitted.") if parsed.hostname != "mp.weixin.qq.com": raise ValueError("Only mp.weixin.qq.com URLs are permitted.") if parsed.port not in {None, 443}: raise ValueError("Nonstandard ports are not permitted.") if not parsed.path.startswith("/s"): raise ValueError("The URL is not a supported WeChat article URL.") if parsed.username or parsed.password: raise ValueError("URLs containing credentials are not permitted.") return normalized ``` 2. Apply validation to every `seed_urls` entry before it is added to `candidate_urls`. 3. Resolve destination hostnames and reject loopback, private, link-local, multicast, reserved, and unspecified IPv4 and IPv6 addresses. 4. Disable automatic redirects or validate every redirect destination before following it. 5. Repeat validation immediately before each HTTP request and browser navigation to reduce time-of-check/time-of-use and DNS rebinding risks. 6. Pass the validated canonical URL—not the original untrusted URL—to the extraction and engagement helpers. 7. Use a new temporary browser profile for public collection. Only reuse an authenticated persistent profile after explicit user consent. 8. Isolate browser execution with restricted filesystem access, no unnecessary extensions, and egress limited to required WeChat domains. 9. Add tests covering loopback addresses, private IP ranges, IPv6 literals, encoded hostnames, user-info syntax, nonstandard ports, redirects, and DNS rebinding cases. 10. Avoid writing response excerpts from restricted or unexpected destinations into reports. ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:18
Finding

Unpinned and Unverifiable Third-Party Dependency Installation

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The stated purpose omits that the skill performs Playwright automation, saves raw HTML, handles persistent sessions, and includes captcha/manual verification flow. Those behaviors can capture sensitive page data, interact with authenticated services, and normalize manual login challenges in a workflow that users may incorrectly perceive as simple report generation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The stated purpose omits that the skill performs Playwright automation, saves raw HTML, handles persistent sessions, and includes captcha/manual verification flow. Those behaviors can capture sensitive page data, interact with authenticated services, and normalize manual login challenges in a workflow that users may incorrectly perceive as simple report generation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The stated purpose omits that the skill performs Playwright automation, saves raw HTML, handles persistent sessions, and includes captcha/manual verification flow. Those behaviors can capture sensitive page data, interact with authenticated services, and normalize manual login challenges in a workflow that users may incorrectly perceive as simple report generation.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding

The README instructs users to run npx playwright install chromium without pinning an exact package version, which can cause execution of whatever Playwright package version npm resolves at install time. In a supply-chain compromise or unexpected upstream release scenario, users could fetch and run unreviewed code during setup, and this skill’s browser-heavy workflow makes that setup step plausible and likely to be followed.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill advertises no explicit tool restrictions even though it appears to require file access, networking, and shell execution. That under-scopes a skill that can access local files and remote content, making review, sandboxing, and least-privilege enforcement much harder and increasing the chance of unintended data access or command execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This code issues HTTP requests to arbitrary URLs and later uses them to discover and retrieve WeChat article content. There is no confirmation prompt, user-facing log/print, or inline warning here that the skill will transmit the user's topic and accessed URLs to external services.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The manifest describes collecting WeChat articles into a local structured report, which justifies network retrieval and local file output. However, this file additionally depends on a system Node.js runtime and invokes external helper scripts via subprocess, introducing code-execution capability that is not stated in the skill purpose and is stronger than the reporting task itself requires at the manifest level.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The function invokes subprocesses to run helper scripts, which is a safety-relevant operation because it delegates behavior outside the Python runtime. In this file there is no visible confirmation prompt or disclosure that external scripts will be executed as part of report generation.

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 · runtime.py (reported line 304)May include surrounding context.

python
def run_node_script(script_path: Path, *args: str, cwd: Path) -> Any:
    command = [require_node(), str(script_path), *args]
    completed = subprocess.run(
        command,
        cwd=cwd,
        capture_output=True,

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill uses browser automation with a persistent profile directory to fetch blocked WeChat content and collect engagement data, which can reuse authenticated session state and access data beyond what is publicly visible. In this context, the feature directly increases privacy and account-security risk because it may act with the operator's logged-in browser identity without explicit per-run consent or tight scope controls.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code persists raw JSON and markdown reports containing fetched article metadata, URLs, notes, and processing results into the workspace. There is no confirmation prompt, print/log message, or inline warning here informing the user that files will be created at those paths.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script creates a persistent Playwright browser context using the supplied profile directory, which stores browsing session state and potentially authentication data on disk. There is no confirmation prompt, warning message, or explanatory comment disclosing that local browser/session data will be written and reused.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The description uses broad verbs like 'Discover or accept multiple WeChat article URLs for one topic' without clearly constraining when the skill should activate or what user intent is required. In an agentic environment, vague activation criteria can cause the skill to run on loosely related prompts, leading to unintended collection of external content and downstream file writes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest description does not warn that the skill writes both a comparison report and raw JSON into a local directory. If selected by an agent or user without clear notice, this can result in unexpected persistence of scraped article data, metadata, and derived content, increasing privacy, data handling, and workspace integrity risks.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This file includes user-facing error/report strings in Chinese, such as the Node.js installation error and extensive report text, but does not offer any language selection or opt-in. That can violate a language/locale policy when a skill implicitly forces one language for all users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script emits natural-language status messages only in Chinese in the note field, regardless of user preference or locale. This is a language-policy concern because it imposes a specific language without any opt-in or fallback.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.