Back to skill

Security audit

wxauto

Security checks for vulnerabilities and agentic risk

Overview

This WeChat automation skill is not clearly malicious, but it needs review because it can access private chats, send messages, and automatically run an unverified local service while transmitting tokens over configurable plaintext HTTP.

Install only if you trust the REST service directory and understand that the skill can read private WeChat messages, send messages, list contacts/groups, and keep a helper service running. Use a strong non-default token, avoid passing tokens on the command line, keep the API bound to loopback, do not use remote HTTP endpoints, and review the cloned service code before allowing automatic startup.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/wxapi.py:228
Finding

Bearer Token and Sensitive WeChat Data Can Be Transmitted to an Arbitrary Plaintext Endpoint

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/wxapi.py:545
Finding

Authentication Token Is Disclosed Through Help Output and Command-Line Arguments

Content
View full analysis
env vars > service_status.json > config.yaml > defaults): - WXAPI_BASE_URL or WXAPI_HOST/WXAPI_PORT: API server address - WXAPI_TOKEN: Authentication token - ~/.wxautox/service_status.json: Auto-detected from running service - WXAPI_CONFIG: Path to config.yaml """ parser = argparse.ArgumentParser(description="WeChat API Tool", epilog=epilog) parser.add_argument("--base-url", help=f"API base URL (default: {BASE_URL})") parser.add_argument("--token", help=f"Auth token (default: {TOKEN})") ``` ```powershell # SKILL.md:74 python wxapi.py --base-url "http://localhost:9000" --token "my-token" send "好友" "消息" ``` ### Technical Analysis The resolved authentication token is interpolated directly into the argparse epilog and the `--token` option's help text. Running the program without a subcommand causes `parser.print_help()` to execute, while standard help handling also exposes this text. Thus, a token loaded from an environment variable or configuration file can be printed in cleartext even when the user did not enter it on the current command line. The documentation additionally encourages users to pass the token as a command-line argument. Command-line secrets may be retained in shell history and can be exposed through process inspection, terminal recording, Agent execution logs, monitoring products, or diagnostic output. ### Attack Path 1. A valid bearer token is loaded from `WXAPI_TOKEN` or `config.yaml`. 2. The user invokes the script with `--help` or without a subcommand. 3. The resolved token is printed to the terminal as part of ...[truncated 768 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/wxapi.py:22
Finding

Predictable Default Bearer Token Permits Weak Authentication

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/wxapi.py:34
Finding

Unpinned Third-Party Components and Automatic Execution of Unverified Service Code

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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (17)

Tainted flow: 'base_url' from os.environ.get (line 129, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
91% confidence
Finding

The service endpoint can be influenced by environment/config sources and is fetched over plain HTTP with no validation that it is truly local or trusted. If an attacker can set WXAPI_BASE_URL/WXAPI_HOST/WXAPI_PORT or poison the status/config files, the tool may probe an attacker-controlled host and later send WeChat data and bearer tokens to it.

Content

Scanner excerpt · scripts/wxapi.py (reported line 58)May include surrounding context.

python
def check_service_alive(base_url):
    """Check if service is responding."""
    try:
        resp = requests.get(f"{base_url}/", timeout=3)
        return resp.status_code == 200
    except Exception:
        return False

Tainted flow: 'url' from os.environ.get (line 236, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
96% confidence
Finding

GET requests are sent to a base URL derived from environment variables and local config/status files, and they include a bearer token in the Authorization header. In this skill context, that means a poisoned configuration can redirect requests for status or metadata to an attacker-controlled server, leaking authentication material and enabling SSRF-like outbound access.

Content

Scanner excerpt · scripts/wxapi.py (reported line 239)May include surrounding context.

python
url = f"{BASE_URL}{endpoint}"
    try:
        if method == "GET":
            resp = requests.get(url, headers=get_headers(), timeout=10)
        else:
            resp = requests.post(url, headers=get_headers(), json=data or {}, timeout=10)
        return resp.json()

Tainted flow: 'url' from os.environ.get (line 236, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
98% confidence
Finding

POST requests transmit contact identifiers and message content to whatever BASE_URL is resolved from environment/config/state files. In this WeChat automation skill, misdirecting these requests can exfiltrate private chats, friend/group data, and the bearer token to an attacker-controlled service.

Content

Scanner excerpt · scripts/wxapi.py (reported line 241)May include surrounding context.

python
if method == "GET":
            resp = requests.get(url, headers=get_headers(), timeout=10)
        else:
            resp = requests.post(url, headers=get_headers(), json=data or {}, timeout=10)
        return resp.json()
    except requests.exceptions.ConnectionError:
        print("Error: Cannot connect to service. Start with: python run.py")

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documented purpose understates important behaviors: the skill can auto-start and manage a backend service, read local status/config files for autodiscovery, and claims support for accepting friend requests without showing that functionality. This mismatch can mislead users and agents about the true authority and data access of the skill, increasing the chance of unintended process execution, local data exposure, or over-trust.

Content

No source excerpt is available for this finding.

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/wxapi.py (reported line 78)May include surrounding context.

python
print(f"Starting service from {service_dir}...")
    try:
        # Set environment for proper encoding
        env = os.environ.copy()
        env['PYTHONIOENCODING'] = 'utf-8'
        
        # Start service in background

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares broad capabilities in practice—environment access, filesystem reads, network access, and shell/process control—without any explicit tool-scope restrictions. That makes the skill more dangerous than its metadata suggests, because an agent may invoke powerful behaviors such as reading local config, auto-starting services, or sending messages without a constrained permission model.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This skill can read chat history and monitor incoming WeChat messages, but the description does not prominently warn that it handles sensitive private communications. In context, that is security-relevant because users may authorize the skill for convenience without understanding it can access message content and ongoing conversation data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill may automatically start a local backend service and perform automated message-sending actions, but that automation risk is not clearly disclosed as a high-visibility warning. In this context, hidden process launch plus automated messaging can cause unintended execution and actions on the user's WeChat account without informed approval.

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 · SKILL.md (reported line 269)May include surrounding context.

headers = {"Authorization": "Bearer token", "Content-Type": "application/json"} body = {"who": "好友名", "msg": "消息内容"} resp = requests.post("http://localhost:8000/v1/wechat/send", headers=headers, json=body) print(resp.json())

text

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · SKILL.md (reported line 269)May include surrounding context.

headers = {"Authorization": "Bearer token", "Content-Type": "application/json"} body = {"who": "好友名", "msg": "消息内容"} resp = requests.post("http://localhost:8000/v1/wechat/send", headers=headers, json=body) print(resp.json())

text

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

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

headers = {"Authorization": "Bearer token", "Content-Type": "application/json"} body = {"who": "好友名", "msg": "消息内容"} resp = requests.post("http://localhost:8000/v1/wechat/send", headers=headers, json=body) print(resp.json())

text

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest describes WeChat automation functions such as sending messages, reading chats, listening for messages, and contact management via a RESTful API. In addition to calling that API, this code locates a separate service directory and launches run.py as a background subprocess, which is a host-level process management capability not stated in the skill purpose.

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/wxapi.py (reported line 83)May include surrounding context.

python
# Start service in background
        if sys.platform == "win32":
            subprocess.Popen(
                [sys.executable, "run.py"],
                cwd=str(service_dir),
                env=env,

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/wxapi.py (reported line 90)May include surrounding context.

python
creationflags=subprocess.CREATE_NO_WINDOW | subprocess.DETACHED_PROCESS
            )
        else:
            subprocess.Popen(
                [sys.executable, "run.py"],
                cwd=str(service_dir),
                env=env,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

If no service is found, the tool may automatically start an external background process without explicit confirmation. In a security-sensitive environment, silent process creation increases attack surface and can cause unreviewed code in a discovered service directory to run under the user's account.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The generic API helper sends request data, including chat recipients and message bodies from commands like send and send-chat, over HTTP to the configured service. The file lacks any clear disclosure that user-provided message content and contact metadata will be transmitted to a local or configured API endpoint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code fetches chat history from the WeChat API and prints message contents and senders directly to stdout. Although the function has a docstring, there is no explicit user disclosure that running it will expose potentially sensitive private message content in terminal output or logs.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.