Back to skill

Security audit

WeChat MP Reader

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent for WeChat article/account retrieval, but it stores WeChat backend login sessions in plaintext and can fetch arbitrary URLs, so it should be reviewed before installation.

Install only if you are comfortable letting the skill use a WeChat MP backend session, including QR login and cookie/token reuse. Use it in an isolated workspace, do not commit or share scripts/cache/session files, pass only real https://mp.weixin.qq.com article URLs, and avoid following the external memory-file checklist unless you explicitly intend to expose that context.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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/wechat_mp_reader.py:107
Finding

Unrestricted article URL fetching enables server-side request forgery

Content
View full analysis
str: resp = requests.get(url, headers={"User-Agent": USER_AGENT}, timeout=timeout) resp.raise_for_status() resp.encoding = resp.apparent_encoding or resp.encoding return resp.text ``` The same URL can subsequently be opened by Playwright: ```python def fetch_article_via_playwright(url: str, timeout: int = 20000) -> dict[str, Any]: if sync_playwright is None: raise RuntimeError("playwright not available") page = None browser = None with sync_playwright() as p: browser = p.webkit.launch(headless=True) try: page = browser.new_page( user_agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15", viewport={"width": 1440, "height": 2200}, ) page.goto(url, wait_until="domcontentloaded", timeout=timeout) ``` The CLI accepts the URL without validating its destination: ```python p_article.add_argument("url", help="WeChat article URL") ``` ### Technical Analysis The Skill describes the input as a WeChat article URL, but it does not enforce that requirement. There is no validation of: - URL scheme - Normalized hostname - Destination port - Embedded credentials - IP literals - DNS resolution results - Redirect destinations - Loopback, private, link-local, or reserved address ranges Consequently, an attacker who controls the article argument can cause the host running the Skill to issue requests to arbitrary network destinations. The initial request uses `requests.get()`, which follows redirects by default. If the returned page is ...[truncated 1683 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/wechat_mp_reader/session_store.py:29
Finding

WeChat backend session credentials are persisted without secure file protections

Content
View full analysis
str: target = Path(path) if path else DEFAULT_SESSION_PATH _ensure_parent(target) data = { "cookie": str(session.get("cookie", "") or "").strip(), "token": str(session.get("token", "") or "").strip(), } target.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8") return str(target) ``` ### Technical Analysis The function writes the complete WeChat MP backend cookie and token to an unencrypted JSON file. These values represent an authenticated backend session and should be treated as high-value credentials. The implementation does not: - Explicitly set the file mode to owner-only access, such as `0600` - Securely create the file before writing sensitive data - Prevent following symbolic links - Verify file ownership - Verify that the destination is a regular file - Restrict the caller-supplied `--session-path` to a controlled directory - Use an atomic write-and-replace process The resulting permissions depend on the process umask and preexisting filesystem object. `Path.write_text()` also follows symbolic links. If an attacker can prepare the selected path or a parent directory, the write may disclose credentials or overwrite another file writable by the process. ### Attack Path 1. A user supplies WeChat credentials through the environment and runs `session save`, or completes the QR-login workflow. 2. `save_session_file()` serializes the full cookie and token. 3. The data is written under the process’s current umask without enforcing owner-only permissions. 4. A local process with filesystem access reads the resulting session file and obtains the reusable credentials. 5. Al ...[truncated 799 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/wechat_mp_reader/qr_login.py:27
Finding

QR-login state cookies and authentication artifacts are retained insecurely

Content
View full analysis
str: _ensure_parent(STATE_PATH) STATE_PATH.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8") return str(STATE_PATH) ``` The persisted state includes the login cookies: ```python def login_start() -> dict[str, Any]: session = _new_session() resp = session.get(f"{BASE_URL}/", timeout=20) resp.raise_for_status() qr_info = _extract_qr_info(session, resp.text) qr_image_path = _save_qr_image(session, qr_info["qr_url"]) state = { "uuid": qr_info["uuid"], "qr_url": qr_info["qr_url"], "qr_image_path": qr_image_path, "created_at": int(time.time()), "cookies": requests.utils.dict_from_cookiejar(session.cookies), } state_path = _save_state(state) ``` ### Technical Analysis The QR-login state file contains cookies and identifiers associated with an active authentication flow. It is stored in plaintext using normal file creation semantics, without explicit owner-only permissions, symbolic-link protection, ownership checks, or atomic creation. The implementation records `created_at` but does not enforce an expiration interval when loading or polling the state. It also does not delete `login-state.json` or the QR image after successful authentication, failure, or timeout. Although these pre-authentication cookies are not necessarily equivalent to the final authenticated session, they are sensitive because they bind subsequent status polling and credential capture to the QR-login flow. ### Attack Path 1. A victim invokes `session login-start`. 2. The Skill writes the QR UUID, QR URL, local QR path, creation time, and Requests session cookies to `scripts/cache/login-state.json`. 3. ...[truncated 1013 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
CURRENT_TASK.md:56
Finding

Project handoff instructions request access to Agent memory outside the Skill directory

Content
View full analysis
--with-account-articles` directly via the main script. ``` ### Technical Analysis The declared Skill functionality is limited to reading WeChat articles, resolving accounts, listing articles, and managing the Skill’s WeChat session. Reading general Agent memory files outside the project is not required for those operations. The two referenced memory files are not present in the audited project, and their contents were not inspected. Therefore, the finding concerns the cross-scope access instruction itself rather than any claim about those files. If an Agent follows the handoff checklist in a broader workspace, information from previous sessions may be loaded into the current context. This violates least-privilege principles and may expose unrelated user or operational state to a Skill that does not need it. ### Attack Path 1. The Skill or its handoff document is loaded into an Agent environment containing a shared `memory/` directory. 2. The Agent follows the resume checklist. 3. The Agent reads `memory/2026-04-01.md` and `memory/2026-04-02.md`, although those files are outside the audited Skill and unnecessary for article retrieval. 4. Unrelated historical context enters the current execution context. 5. That information may influence subsequent actions or be exposed through later outputs, depending on the contents of the external files and the Agent’s behavior. ### ...[truncated 522 chars]
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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared purpose is article retrieval, but the instructions also implement QR-based login, session acquisition, cookie/token persistence, login polling, and local storage of authentication artifacts. That mismatch is dangerous because it hides credential-handling behavior behind a content-fetching description, increasing the chance that users or orchestrators grant access without understanding that sensitive authentication state will be captured and stored.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Prefer the bundled Python prototype at `scripts/wechat_mp_reader.py`.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Prefer the bundled Python prototype at `scripts/wechat_mp_reader.py`.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Prefer the bundled Python prototype at `scripts/wechat_mp_reader.py`.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

This code implements a full QR-based WeChat MP login flow and persists resulting authenticated session material, which exceeds the declared article-reading purpose of the skill. In context, this is dangerous because it enables acquisition of a reusable authenticated publisher/admin session rather than merely fetching public article content, expanding the capability into account access and session capture.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

On successful login, the code extracts a token and serialized cookie string, then saves them via save_session_file for later reuse. Reusable authenticated session credentials can enable account takeover of the logged-in WeChat MP session if the saved file is accessed by another process, user, or attacker.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest describes a reader skill for fetching WeChat article content, identifying accounts, and listing articles, but this handoff explicitly states the skill also manages WeChat MP backend session state and performs QR login. Maintaining authenticated backend sessions is a broader operational capability than the read-oriented behavior described in the manifest, and is not disclosed there.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · CURRENT_TASK.md (reported line 58)May include surrounding context.

md
## Resume checklist for a new session
1. Read `skills/wechat-mp-reader/CURRENT_TASK.md`
2. Read `skills/wechat-mp-reader/SKILL.md`
3. Read `skills/wechat-mp-reader/references/design.md`
4. Read `memory/2026-04-01.md`
5. Read `memory/2026-04-02.md`

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill declares broad operational behavior involving environment access, local file reads/writes, and network activity, but does not declare any explicit tool scope or permission boundaries. This increases the risk of over-privileged execution because an agent or reviewer cannot easily tell what capabilities are required or restrict the skill to the minimum necessary set.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill says 'Use this skill for 微信公众号文章抓取、公众号反查、文章列表拉取、全文提取,' which presents the activation/instruction text solely in Chinese. This imposes a language/locale preference without explicit user opt-in or a documented reason that the skill must operate only in Chinese.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The documentation describes saving and using an authenticated WeChat MP backend session, including QR-based login, but does not clearly disclose the sensitivity of the stored credentials or the risks of local persistence. This can mislead users into authorizing backend access without understanding that cookies/tokens may grant broader account-level capabilities than public article scraping.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The natural-language workflow encourages users to search accounts and list recent articles, but it does not clearly warn that these actions depend on authenticated access to WeChat MP backend APIs rather than purely public data. That omission can cause users to trigger privileged operations without informed consent and underestimate the security/privacy implications of providing or reusing a logged-in session.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The session save path persists WeChat MP backend cookie and token material to disk, which are sensitive authentication secrets. Storing them without an explicit warning, consent flow, or clear guidance on secure file permissions increases the chance of accidental credential exposure through shared machines, backups, logs, or repository inclusion.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code transmits a session cookie and token to a remote service via request headers and query parameters. There is no confirmation prompt, user-facing log, or inline warning indicating that sensitive authentication material will be used over the network.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The session headers hard-code Accept-Language to prefer zh-CN, and the login flow repeatedly fixes lang/userlang to zh_CN elsewhere in the file. This is a natural-language locale policy concern because the skill enforces a specific language setting without any visible opt-in or documented reason in the file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The start-login request explicitly sets lang to zh_CN and embeds lang=zh_CN in the redirect URL, and similar hard-coded locale values appear in later requests. This indicates the skill is designed to force a specific language/locale rather than allowing user choice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The login_start path writes login state, including session cookies from the requests session, to a JSON file on disk without any visible warning, consent, or protection shown here. Even if these are pre-auth cookies, they are authentication-related state that can aid session continuation, correlation, or later credential exchange if exposed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code persists authentication material (cookie and token) to a predictable JSON file under the project cache directory without any permission hardening, encryption, or user warning. On multi-user systems, shared workspaces, backups, or accidental source/package inclusion, these secrets could be exposed and reused to access the associated WeChat management session.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The manifest frames the skill as fetching and reading WeChat Official Account content, but this helper also retrieves authentication material from process environment variables. Accessing credential-like secrets is a stronger capability than simple content extraction and is not explicitly justified by the stated purpose in the manifest.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill hard-codes lang: "zh_CN" in natural-language request parameters when calling WeChat MP backend APIs. This enforces a specific locale without offering user opt-in or documenting why the locale is required, which matches the policy's locale-choice concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The article-listing API request includes a hard-coded lang: "zh_CN" parameter. This is a natural-language locale constraint imposed by the skill and is not presented as an opt-in or justified region-specific requirement in the file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The code writes account data to a persistent JSON cache file via target.write_text(...), but there is no confirmation prompt, logging, print statement, docstring, or comment disclosing that user-supplied account information will be stored on disk. For a code file, persistent file writes affecting user data should have at least some visible disclosure unless that behavior is clearly documented elsewhere.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The code forces the request language to "zh_CN" with no visible opt-in or configurability. This can violate language or locale policy when a skill is expected to respect user preferences unless a locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The function fetches the QR image over the network and saves it to wechat-login-qr-real.png using write_bytes at L112. Although this is part of login flow, the file write has no visible confirmation, print/log message, or explanatory comment/docstring in this file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The function reads session cookie and token values from environment variables, which are sensitive credentials. The code provides no comment, docstring, or user-visible disclosure explaining that credential material is sourced from the environment.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.