Back to skill

Security audit

wechat-article-getter

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real WeChat article reader, but it automatically installs unpinned browser tooling and renders caller-supplied URLs in an unsafe browser configuration.

Review before installing. Use only in an isolated, unprivileged environment with outbound network restrictions; avoid running setup as root or with sudo; preinstall pinned dependencies through a reviewed process; and only pass exact https://mp.weixin.qq.com URLs until URL and redirect validation are fixed.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fetch_article.py:204
Finding

Weak URL Validation Enables Server-Side Request Forgery Through Headless Chromium

Content
View full analysis
Remediation
View remediation
bool: try: parsed = urlparse(url) except ValueError: return False return ( parsed.scheme == "https" and parsed.hostname == "mp.weixin.qq.com" and parsed.username is None and parsed.password is None and parsed.port in (None, 443) ) ``` Apply the following additional controls: 1. Permit only HTTPS and the exact approved hostname, or use an explicit allowlist if approved subdomains are required. 2. Reject URL credentials, fragments where unnecessary, nonstandard ports, malformed hostnames, and ambiguous IP representations. 3. Resolve the hostname and reject loopback, private, link-local, multicast, reserved, and cloud metadata address ranges. 4. Intercept every browser request and abort requests whose resolved destination is outside the approved host policy. 5. Validate redirect destinations rather than trusting the initial URL alone. 6. Apply outbound network restrictions at the container or firewall layer so the process cannot reach internal services or metadata endpoints. 7. Set conservative page, redirect, and resource limits to reduce browser-driven network abuse. ]]>

T08 · Insecure Dependencies

Error
Location
scripts/fetch_article.py:49
Finding

Automatic Installation of Unpinned Remote Dependencies Creates a Supply-Chain Execution Risk

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fetch_article.py:80
Finding

Chromium Sandbox Is Disabled While Rendering Remote Content

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill description understates behavior by presenting itself as an article reader while also initiating package/browser installation and claiming a mirror-site fallback that is not actually implemented as described. This mismatch is dangerous because users or orchestrators may approve execution under false assumptions, leading to unexpected code installation, network activity, and data handling outside the declared purpose.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill advertises executable behavior that uses shell, network access, and file writes, but it does not declare any explicit tool scope or permissions boundaries. That increases the chance an agent framework will grant broader capabilities than intended, making abuse, unexpected installation, or unsafe execution harder to audit and constrain.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill self-installs packages and a browser binary, materially increasing its privileges and operational scope beyond simple article extraction. In a security-sensitive agent environment, silent software installation is dangerous because it changes the host state, pulls executable code from the network, and may bypass normal deployment review controls.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
96% confidence
Finding

The skill performs pip install automatically during normal execution, causing network access, package installation, and code execution from external repositories without prior approval. Although the command is not shell-injected, this creates a significant supply-chain risk and gives the skill capabilities beyond its stated purpose of reading articles.

Content

Scanner excerpt · scripts/fetch_article.py (reported line 59)May include surrounding context.

python
except ImportError:
        import subprocess
        print("📦 首次运行:安装 playwright + beautifulsoup4 ...")
        subprocess.check_call([sys.executable, "-m", "pip", "install", "playwright", "beautifulsoup4", "-q"])

    # 检查 chromium 是否已安装
    from pathlib import Path as _P

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
94% confidence
Finding

This code automatically installs Chromium at runtime by spawning a subprocess, which expands the skill from content retrieval into software installation and execution. In an agent context, this can trigger large, unreviewed downloads and execute newly installed tooling, increasing supply-chain and environment-tampering risk even though the command arguments are not shell-injected.

Content

Scanner excerpt · scripts/fetch_article.py (reported line 68)May include surrounding context.

python
if not has_chromium:
        import subprocess
        print("🌐 首次运行:安装 Chromium 浏览器(~110MB)...")
        subprocess.check_call([sys.executable, "-m", "playwright", "install", "chromium"])
        print("✅ Chromium 安装完成")

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest says the skill 'falls back to mirror-site search' in order to support reading or extracting the article when headless browsing is unavailable. In practice, the fallback only queries third-party sites and returns a failure message indicating manual extraction is still required, so the implemented behavior does not match the promised extraction capability.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code automatically falls back to querying third-party mirror/search sites when Playwright extraction fails. Although the function docstring mentions a mirror fallback, there is no visible runtime disclosure in the CLI path that user-supplied or article-derived data may be sent to external sites.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The module docstring presents the setup instructions only in Chinese ('一键安装', '运行一次即可') with no indication that the skill is China-specific or that other languages are supported. This creates a natural-language locale policy issue because the skill imposes a language choice on users without opt-in or justification.

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 · scripts/setup.py (reported line 13)May include surrounding context.

python
def main():
    # 1. 安装 playwright Python 包
    print("📦 Installing playwright...")
    subprocess.check_call([sys.executable, "-m", "pip", "install", "playwright", "beautifulsoup4", "-q"])

    # 2. 安装 Chromium 浏览器(~200MB)
    print("🌐 Installing Chromium browser...")

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 · scripts/setup.py (reported line 17)May include surrounding context.

python
# 2. 安装 Chromium 浏览器(~200MB)
    print("🌐 Installing Chromium browser...")
    subprocess.check_call([sys.executable, "-m", "playwright", "install", "chromium"])

    # 3. 安装系统依赖(Linux)
    print("📋 Installing system dependencies...")

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 · scripts/setup.py (reported line 22)May include surrounding context.

python
# 3. 安装系统依赖(Linux)
    print("📋 Installing system dependencies...")
    try:
        subprocess.check_call([sys.executable, "-m", "playwright", "install-deps", "chromium"])
    except subprocess.CalledProcessError:
        print("⚠️  install-deps failed (may need sudo). Try:")
        print("   sudo npx playwright install-deps chromium")

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
50% confidence
Finding

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

Content

Scanner excerpt · scripts/setup.py (reported line 24)May include surrounding context.

python
try:
        subprocess.check_call([sys.executable, "-m", "playwright", "install-deps", "chromium"])
    except subprocess.CalledProcessError:
        print("⚠️  install-deps failed (may need sudo). Try:")
        print("   sudo npx playwright install-deps chromium")

    print("\n✅ Setup complete! You can now use fetch_article.py")

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 · scripts/setup.py (reported line 25)May include surrounding context.

python
subprocess.check_call([sys.executable, "-m", "playwright", "install-deps", "chromium"])
    except subprocess.CalledProcessError:
        print("⚠️  install-deps failed (may need sudo). Try:")
        print("   sudo npx playwright install-deps chromium")

    print("\n✅ Setup complete! You can now use fetch_article.py")

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The docstring presents _fetch_via_mirror as a working fallback path, but its implementation requires title_hint, and fetch_wechat_article calls it with only the URL. As a result, the documented fallback behavior is contradicted by the real control flow, which makes mirror searching effectively unreachable.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.