Back to skill

Security audit

WeChat Articles Reader

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but it needs Review because it can load any HTTP URL in an unsandboxed browser and automatically send screenshots even when the user only asked for a summary.

Install only if you are comfortable with a skill that runs local browser automation, installs or depends on global/system packages, and sends article screenshots to the active channel. Prefer a revised version that validates mp.weixin.qq.com URLs, keeps Chrome sandboxing enabled, makes screenshots opt-in, uses local pinned dependencies, and writes screenshots only to a private temporary directory.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (6)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/fetch_wechat.js:61
Finding

Unrestricted Browser Navigation Enables Server-Side Request Forgery

Content
View full analysis
a.startsWith('http')); ``` ```js await page.goto(url, { waitUntil: 'networkidle', timeout: 30000 }); ``` From `scripts/screenshot_wechat.js`: ```js const args = process.argv.slice(2); const url = args.find(a => a.startsWith('http')); ``` ```js await page.goto(url, { waitUntil: 'load', timeout: 30000 }); ``` ### Technical Analysis The scripts accept any argument beginning with `http` and pass it directly to Playwright. They do not enforce the Skill's declared `mp.weixin.qq.com` scope, require HTTPS, reject embedded credentials or unusual ports, constrain redirects, or block loopback, private, link-local, and cloud metadata addresses. Consequently, Chrome can make requests using the execution host's network access rather than the requesting user's access. Browser navigation also follows redirects, so validating only the initial URL would remain insufficient. ### Attack Path 1. An attacker supplies a URL such as an internal HTTP service or an attacker-controlled URL that redirects to one. 2. The prefix check accepts the URL because it begins with `http`. 3. Playwright navigates to the target from the Skill execution environment. 4. `fetch_wechat.js` extracts visible text, or `screenshot_wechat.js` captures the rendered response. 5. The resulting internal content is exposed through command output or the screenshot workflow. ### Impact Assessment An attacker may access HTTP resources reachable from the execution environment, including localhost services, private-network administration interfaces, and potentially cloud metadata endpoints. The practical scope depends on the host's network placement ...[truncated 218 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:77
Finding

Mandatory Screenshot Transmission Can Exfiltrate Retrieved Content

Content
View full analysis
--json` (required) 2. **Take screenshot** — `node scripts/screenshot_wechat.js --out=/tmp/wechat_article.png` (best-effort, run in parallel with step 1) 3. **Send screenshot** — `message(action=send, media=/tmp/wechat_article.png)` if step 2 succeeded; skip silently if it failed 4. **Send summary** — text summary following the output format below 5. **Clean up** — delete the temporary screenshot file ``` ```markdown 1. **Fetch text** — run `fetch_wechat.js --json` to get title, author, date, content 2. **Take screenshot** — run `screenshot_wechat.js --out=/tmp/wechat_screenshot.png` 3. **Send screenshot** — use `message(action=send, media=/tmp/wechat_screenshot.png)` to push the image to the channel 4. **Send text summary** — reply with the two-part format (📌 Overview + 🔎 Deep Dive) 5. **Delete temp file** — `rm /tmp/wechat_screenshot.png` Steps 1 and 2 can run in parallel. Step 3 must complete before step 4 (image first, text second). **Never skip the screenshot.** ``` ### Technical Analysis The Skill directs the Agent to capture and transmit a full-page screenshot even when the user requests only reading, explanation, or summarization. This exceeds the minimum data handling required for the declared function. When combined with the unrestricted URL navigation vulnerability, the instruction creates a direct disclosure channel: content retrieved from an internal or otherwise sensitive endpoint can be captured and sent to the active messaging channel. Deleting the local temporary file afterward does not undo that transmission. The document is also internally inconsistent: one workflow describes the screenshot as best-effort, while another says it must never be skipped. The ...[truncated 1014 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fetch_wechat.js:28
Finding

Environment-Derived Paths Are Interpolated into Shell Commands

Content
View full analysis
/dev/null | head -1`, { encoding: 'utf-8' } ).trim(); ``` The same construction is used in `scripts/screenshot_wechat.js`: ```js const { execSync } = require('child_process'); const searchDirs = [ process.env.NVM_DIR || `${process.env.HOME}/.nvm`, '/usr/lib/node_modules', '/usr/local/lib/node_modules', '/usr', ].join(' '); const found = execSync( `find ${searchDirs} -name 'playwright-core' -path '*/node_modules/*' -type d 2>/dev/null | head -1`, { encoding: 'utf-8' } ).trim(); ``` ### Technical Analysis `execSync()` executes the constructed string through a shell. `NVM_DIR`, or `HOME` when `NVM_DIR` is absent, is concatenated into that command without shell quoting or argument separation. Shell metacharacters in either environment variable are therefore interpreted as command syntax. The vulnerable branch is reached when the initial `require('playwright-core')` call fails. Exploitation requires the attacker or a compromised launcher to influence the process environment, but successful exploitation executes arbitrary commands with the same operating-system privileges as the Skill process. ### Attack Path 1. An attacker gains control over `NVM_DIR` or `HOME` in the environment used to launch the Skill. 2. The attacker inserts shell syntax into the variable value. 3. `require('playwright-core')` fails, causing fallback dependency discovery to run. 4. The unquoted value is interpolated int ...[truncated 571 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/screenshot_wechat.js:53
Finding

Unrestricted Screenshot Output Path Allows Arbitrary File Overwrite

Content
View full analysis
a.startsWith('--out=')); const outPath = outArg ? outArg.split('=').slice(1).join('=') : '/tmp/wechat_screenshot.png'; ``` ```js if (articleEl) { const bbox = await articleEl.boundingBox(); await page.screenshot({ path: outPath, fullPage: true, clip: { x: bbox.x, y: bbox.y, width: bbox.width, height: bbox.height }, }); } else { await page.screenshot({ path: outPath, fullPage: true }); } ``` ### Technical Analysis The `--out` argument is accepted as an unrestricted filesystem path and passed directly to Playwright. There is no containment check, existing-file check, symlink defense, exclusive creation, or dedicated output directory. An attacker who can influence script arguments can replace any existing file writable by the Skill process with PNG data. A fixed default path under `/tmp` also creates collision and symlink risks when the environment is shared with other local users. ### Attack Path 1. An attacker supplies `--out=` with the path of an existing file writable by the Skill process, or prepares a symlink at the predictable default path. 2. The script renders the supplied page. 3. Playwright writes the screenshot to the attacker-selected path. 4. The destination file is replaced or corrupted with PNG content. 5. If later cleanup follows the same attacker-controlled path, it may also delete the resulting file. ### Impact Assessment The attacker can corrupt files writable by the Skill process, potentially causing denial of service, configuration damage, or disruption of other applications. The operation writes image data rather than arbitrary attacker-selected bytes, which limits direct code-execution potential. Files outside the process account's permissions cannot be ...[truncated 42 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fetch_wechat.js:88
Finding

Chrome Sandbox Is Disabled While Rendering Untrusted Network Content

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:61
Finding

Unpinned Global Installation of Playwright Dependency

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The code substantially matches the core article-fetching portion of the description: it targets mp.weixin.qq.com articles, uses Playwright with a mobile user agent and webdriver masking to bypass anti-bot checks, and extracts title, author, date, and full article text. However, the description also claims an optional capability to capture a full-page screenshot with lazy-loaded images, which is absent from the code. Additionally, the description says 'read and summarize' articles, but this script only fetches and outputs extracted content; it does not summarize or analyze it. These are material description-to-behavior gaps, so this should be flagged as a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code is narrowly focused on browser automation and screenshotting of WeChat article pages. It does include anti-bot evasion measures and lazy-load handling, which align with part of the description, and it can capture the article region. However, the declared purpose prominently claims the skill can read and summarize articles and extract full article text, title, author, and date. None of those extraction or summarization behaviors are present in this code chunk. Since the actual behavior is materially narrower than the declared capability set, this is a description-behavior mismatch.

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 14)May include surrounding context.

md
1. **Fetch text** — `node scripts/fetch_wechat.js <url> --json` (required)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
1. **Fetch text** — `node scripts/fetch_wechat.js <url> --json` (required)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
1. **Fetch text** — `node scripts/fetch_wechat.js <url> --json` (required)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
1. **Fetch text** — `node scripts/fetch_wechat.js <url> --json` (required)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
1. **Fetch text** — `node scripts/fetch_wechat.js <url> --json` (required)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
2. **Take screenshot** — `node scripts/screenshot_wechat.js <url> --out=/tmp/wechat_article.png` (best-effort, run in parallel with step 1)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
2. **Take screenshot** — `node scripts/screenshot_wechat.js <url> --out=/tmp/wechat_article.png` (best-effort, run in parallel with step 1)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
2. **Take screenshot** — `node scripts/screenshot_wechat.js <url> --out=/tmp/wechat_article.png` (best-effort, run in parallel with step 1)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

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

md
2. **Take screenshot** — run `screenshot_wechat.js --out=/tmp/wechat_screenshot.png`
3. **Send screenshot** — use `message(action=send, media=/tmp/wechat_screenshot.png)` to push the image to the channel
4. **Send text summary** — reply with the two-part format (📌 Overview + 🔎 Deep Dive)
5. **Delete temp file** — `rm /tmp/wechat_screenshot.png`

Steps 1 and 2 can run in parallel. Step 3 must complete before step 4 (image first, text second).

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The workflow mandates always capturing and sending a screenshot, even when the manifest says screenshots are optional and the user may have asked only for summarization. This can cause unnecessary disclosure of article contents, including embedded personal or sensitive material, to the conversation channel without clear need or consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs the agent to automatically send captured screenshots to the channel without explicit warning or confirmation. Because screenshots may include copyrighted, private, or context-sensitive article content, automatic transmission increases the risk of unintentional disclosure beyond what the user requested.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill's purpose is to fetch and extract article text from a provided WeChat URL. However, when dependencies are missing it executes a shell find command across user and system directories, which is an additional host-inspection capability unrelated to article reading itself.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The browser context is hard-coded to locale 'zh-CN' and timezone 'Asia/Shanghai', which imposes a specific language/locale setting on all executions. The policy allows locale constraints only when users can opt in or when the regional restriction is clearly documented and justified, neither of which is present here.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill's purpose is to read and screenshot WeChat articles, but this implementation invokes shell commands (find, head, which) to probe the host environment for installed modules and browser executables. That host-level discovery capability is broader than what is obviously required for article capture and introduces environment inspection behavior outside the manifest's stated scope.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The browser context is hard-coded to use locale 'zh-CN' and timezone 'Asia/Shanghai'. This creates a language/locale policy concern because the skill imposes a specific regional setting on all users without offering a choice or documenting an opt-in.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The manifest frames the skill as reading and summarizing WeChat articles and optionally capturing a screenshot. The screenshot section specifies CSS injection to hide promotional footers, action bars, and contact sections, meaning the captured image is a modified rendering rather than a faithful screenshot of the page as presented.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

Launching a subprocess to inspect the host environment is not part of the manifest's user-facing purpose. While locating Chrome is operationally convenient, using execSync adds a capability beyond direct article retrieval and extraction.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/fetch_wechat.js:35

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/screenshot_wechat.js:27