Back to skill

Security audit

Weixin WeChat Channel

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a WeChat article/draft workflow, but its shipped code is dominated by an insecure remote license gate that sends and stores device/license identifiers without adequate protection or disclosure.

Review before installing. This skill may create drafts in a connected WeChat public account and requires WeChat app credentials, but the included code also sends a stable device fingerprint and license key to a default plaintext HTTP licensing server and saves the reusable license key locally in plaintext. Use only if you trust the publisher and licensing server, prefer an HTTPS license endpoint, protect or rotate any card key used, and verify draft content/account selection before allowing external writes.

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
scripts/license_gate.py:17
Finding
License credentials and machine fingerprint transmitted over plaintext HTTP## Vulnerability Details **File Location**: `scripts/license_gate.py:17-19, 58-103` **Vulnerability Type**: Cleartext transmission of sensitive authentication and device-identification data **Risk Level**: High ### Vulnerable Code ```python # Default license service, overridable through TMO_LICENSE_SERVER _DEFAULT_LICENSE_SERVER = "http://120.27.202.105:8000" _LICENSE_ENV = os.environ.get("TMO_LICENSE_SERVER") LICENSE_SERVER_URL = (_LICENSE_ENV if _LICENSE_ENV is not None and _LICENSE_ENV.strip() != "" else _DEFAULT_LICENSE_SERVER).rstrip("/") ``` ```python def _http_post_json(url: str, payload: dict[str, Any], timeout: float = 10.0) -> dict[str, Any]: body = json.dumps(payload).encode("utf-8") req = urllib.request.Request( url, data=body, headers={"Content-Type": "application/json"}, method="POST", ) try: with urllib.request.urlopen(req, timeout=timeout) as resp: text = resp.read().decode("utf-8") data = json.loads(text or "{}") return data if isinstance(data, dict) else {} except urllib.error.HTTPError as exc: try: text = exc.read().decode("utf-8") data = json.loads(text or "{}") if isinstance(data, dict) and "detail" in data: raise LicenseError(f"授权服务器错误: {data['detail']}") from exc except Exception: pass raise LicenseError(f"授权服务器响应异常 (HTTP {exc.code}),请稍后重试。") from exc except urllib.error.URLError as exc: raise LicenseError("无法连接授权服务器,请检查服务器是否可访问或稍后重试。") from exc ``` ```python def _remote_activate(card_key: str, machine_fp: str) -> dict[str, Any]: if not LICENSE_SERVER_URL: raise LicenseError("未配置授权服务器地址,请设置环境变量 TMO_LICENSE_SERVER。") url = f"{LICENSE_SERVER_URL}/api/activate" data = _http_post_json(url, {"card_key": card_key, "machine_fp": machine_fp}) ...[truncated 3131 chars]
Remediation
## Remediation Suggestions 1. Replace the default endpoint with an HTTPS URL backed by a valid certificate. 2. Reject any license-server URL whose scheme is not `https`. 3. Retain standard certificate and hostname validation; do not introduce an option that disables TLS verification. 4. Avoid sending the reusable card key during every license check. Exchange it once for a revocable, scoped token with a short validity period. 5. Authenticate license responses using a server-side digital signature that the client verifies with an embedded public key. 6. Add replay resistance, such as a client nonce, timestamp, and signed response binding the result to the request. 7. Minimize device information used for licensing and document the collection and retention of the machine fingerprint. 8. Rotate or invalidate card keys that may already have traversed the plaintext service. 9. Apply rate limiting, activation limits, anomaly detection, and revocation controls on the server.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/license_gate.py:187
Finding
Reusable card key stored unencrypted without enforced file permissions## Vulnerability Details **File Location**: `scripts/license_gate.py:44-46, 187-195` **Vulnerability Type**: Insecure local storage of reusable authentication material **Risk Level**: Medium ### Vulnerable Code ```python def _save_json(path: Path, data: dict[str, Any]) -> None: path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8") ``` ```python act = { "version": 2, "key": key, "plan": str(remote.get("plan") or "custom"), "machine_fp": fp, "activated_at": now, "expires_at": expires_at, } _save_json(license_file, act) print(f"授权激活成功,方案: {act['plan']},到期: {_fmt_ts(act['expires_at'])}") return act ``` ### Technical Analysis Following successful activation, the application stores the complete reusable card key in a plaintext JSON file. The generic `_save_json` function uses ordinary directory creation and `Path.write_text` without explicitly creating the file with owner-only permissions. Effective permissions therefore depend on the process umask, existing file permissions, filesystem defaults, and destination directory. The command-line `--license-file` option also allows the caller to select an arbitrary path, increasing the chance that the credential is stored in a shared directory, synchronized folder, project archive, or location readable by other local users. The stored key is subsequently read and sent during routine remote checks, showing that it remains usable authentication material rather than a non-sensitive record. ### Attack Path 1. A user activates the skill using a valid card key. 2. The application constructs the `act` dictionary containing the full key. 3. `_save_json` writes this dictionary in plaintext to the default `license/license.json` path or a path supplied through `--license-file`. 4. The file inherits permissions from normal filesystem creation behavior, with no e ...[truncated 951 chars]
Remediation
## Remediation Suggestions 1. Do not retain the original card key after activation. 2. Exchange the card key for a revocable, machine-bound token with limited scope and lifetime. 3. Store the resulting token in an operating-system credential facility such as Windows Credential Manager, macOS Keychain, or a Linux secret service. 4. If file storage is unavoidable, create the file atomically with owner-only permissions, such as mode `0600` on POSIX systems. 5. Verify and correct permissions on existing files before reading or updating them. 6. Restrict custom license paths to an application-controlled user configuration directory, or warn and refuse paths in shared or project directories. 7. Prevent symlink-based destination redirection and use atomic replacement to avoid partial writes or race conditions. 8. Exclude license files from source-control archives, diagnostic bundles, logs, and cloud synchronization by default. 9. Provide a migration process that removes previously stored raw keys after exchanging them for safer tokens.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The English description promises content-generation workflow automation, but the documented operational entry points center on authorization, machine fingerprint display, and license-status checks. This mismatch suggests the skill performs materially different actions than a user would expect, increasing the risk of deceptive deployment and unintended disclosure of device-related data.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The English description promises content-generation workflow automation, but the documented operational entry points center on authorization, machine fingerprint display, and license-status checks. This mismatch suggests the skill performs materially different actions than a user would expect, increasing the risk of deceptive deployment and unintended disclosure of device-related data.

Context-Inappropriate Capability

High
Confidence
95% confidence
Finding
The code derives a persistent machine fingerprint from hostname, OS, architecture, and MAC-derived data, then uses it for remote licensing. For a skill whose stated purpose is drafting WeChat public-account articles, this device-identification and outbound licensing telemetry is unrelated to core functionality and creates unnecessary privacy and tracking risk, especially because the default server is a raw IP over plain HTTP.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The module sends activation and validation requests to an external server for `/api/activate` and `/api/check`, tying execution of the skill to a third-party licensing endpoint that is unrelated to article generation. Because this occurs over configurable infrastructure and the default endpoint uses unencrypted HTTP, it exposes license keys and device identifiers to interception, misuse, or unauthorized tracking.

Natural-Language Policy Violations

Medium
Confidence
76% confidence
Finding
The README presents the skill entirely in Chinese and describes its operation only in that language, with no indication that users may choose another language or that the locale restriction is intentional and justified. Under the policy, forcing a specific language without opt-in can be a natural-language policy violation.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The README explicitly advertises automatic creation of WeChat public-account drafts in a remote account, but it does not warn users that invoking the skill will modify external state in their公众号后台. That omission weakens informed consent and increases the risk of unintended account actions, especially in agentic environments where a user may not realize content will be pushed to a live backend.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill declares no explicit tool scope or permissions despite documented capabilities involving environment variables, filesystem access, and network communication. This creates an over-privileged and non-transparent skill surface, making it harder for users or a runtime to constrain sensitive actions such as reading secrets, persisting local state, or contacting external services.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill states it will automatically create and save drafts to a WeChat account, but it does not prominently warn that it modifies external account data. Automatic writes to third-party services are risky because mistaken content, account misuse, or unauthorized actions can occur without an explicit confirmation step.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill requires sensitive WeChat credentials and also performs online license validation, yet it does not disclose what credential-, machine-, or environment-related data may be transmitted externally. In this context, lack of a privacy/security notice is dangerous because users may unknowingly expose account-linked secrets or device identifiers to a third-party license server.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The documentation adds a paid card-key scheme and mandatory remote authorization flow that is not justified by the stated article-writing purpose. This expands the trust boundary to an external commercial service and can expose users to unnecessary data transmission, service dependency, and potential abuse if the license server is compromised or operated irresponsibly.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The manifest describes article generation and draft creation, but the documentation separately specifies external network-based license validation. Undeclared outbound communications are security-relevant because they can transmit machine identifiers, license data, or operational metadata to a third party without clear user expectation.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The activation/check flow transmits the machine fingerprint and optionally the card key to a remote server without any meaningful user-facing notice about the network transfer or the sensitivity of the data. In this skill context, users would reasonably expect article drafting assistance, not hidden outbound telemetry and license validation against an external host.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The script stores the license card key together with device-binding and expiry metadata in a local JSON file. Saving reusable license secrets in plaintext without warning or protection increases the risk of credential theft, account sharing abuse, and unintended disclosure through backups, logs, or local compromise.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The entry script’s behavior does not match the advertised skill purpose: it only performs license validation and status reporting, while the manifest claims article generation and draft creation. This mismatch is dangerous because users or orchestrators may grant the skill broader trust and permissions under false assumptions, masking a paywall/telemetry gate or hiding undeclared downstream behavior in other components.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
Collecting and displaying a machine fingerprint is not justified by the stated business purpose of drafting WeChat public account articles. Hardware/device fingerprinting can enable persistent host tracking, bind licenses to a device without meaningful consent, and expose sensitive host-identifying data in logs or support channels.

Missing User Warnings

Low
Confidence
84% confidence
Finding
The README requires WECHAT_APPID and WECHAT_APPSECRET but does not include any guidance on secure storage, scoping, rotation, or avoiding accidental exposure in logs and source control. While this file does not leak the secrets directly, normalizing secret use without handling guidance can lead operators to unsafe deployment practices and credential compromise.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
The manifest description centers the skill on Chinese-language WeChat public account article generation and the rest of the instructions are written only in Chinese. There is no explicit statement that the user may choose another language or that the locale restriction is required for a specific compliance or regional purpose.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The top-level docstring is written entirely in Chinese and the script's user-facing strings are also Chinese-only, indicating a fixed language choice. The file does not present this as an opt-in or document that the tool is intentionally region-specific.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The user-facing argument description and help text are presented only in Chinese, including operational prompts and status descriptions. This imposes a specific language/locale on users without any opt-in or alternative, which matches the language-policy concern for natural-language content in code files.

Static analysis

No suspicious patterns detected.