Back to skill

Security audit

WeixinClawBot Send

Security checks for vulnerabilities and agentic risk

Overview

This WeChat messaging skill is coherent, but it needs review because it can send files and credentials externally and has under-scoped URL and endpoint handling that could leak data.

Install only if you are comfortable letting the agent send WeChat messages and attachments externally. Keep WXCLAW_TOKEN and account files secret, avoid custom WXCLAW_BASE_URL/account baseUrl values unless you fully trust the endpoint, avoid URL attachments from untrusted prompts, and use dry-run or explicit confirmation before sending sensitive files or reports.

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

T09 · Insecure Skill Coding Practices

Error
Location
src/client.ts:201
Finding

Unvalidated API endpoint can disclose bot credentials and sensitive message data

Content
View full analysis
(endpoint: string, body: unknown): Promise { const url = `${this.baseUrl}${endpoint}`; const bodyStr = JSON.stringify(body); const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), SEND_TIMEOUT_MS); try { const res = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", AuthorizationType: "ilink_bot_token", Authorization: `Bearer ${this.token}`, "X-WECHAT-UIN": randomUIN(), }, body: bodyStr, signal: controller.signal, }); ``` The same unvalidated endpoint receives media-upload authorization requests: ```ts const uploadRes = await fetchWithTimeout( `${baseUrl}/ilink/bot/getuploadurl`, { method: "POST", headers: { "Content-Type": "application/json", AuthorizationType: "ilink_bot_token", Authorization: `Bearer ${token}`, "X-WECHAT-UIN": uinHeader, }, body: JSON.stringify(body), }, API_TIMEOUT_MS, ); ``` ...[truncated 2345 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/media.ts:249
Finding

Arbitrary remote file retrieval enables SSRF and forwarding of internal data

Content
View full analysis
{ if (filePath.startsWith("http://") || filePath.startsWith("https://")) { const res = await fetchWithTimeout( filePath, {}, CDN_UPLOAD_TIMEOUT_MS, ); if (!res.ok) { throw new Error(`download ${filePath}: HTTP ${res.status}`); } const buf = Buffer.from(await res.arrayBuffer()); if (buf.length > MAX_FILE_SIZE) { throw new Error( `file too large: ${buf.length} bytes (max ${MAX_FILE_SIZE / 1024 / 1024}MB)`, ); } const urlPath = new URL(filePath).pathname; const name = path.basename(urlPath) || "file"; return { data: buf, name }; } ``` The downloaded response is then passed to the media upload workflow: ```ts const { data, name } = await readFileOrUrl(filePath); const { item } = await uploadFile({ data, filePath: name, toUserId: to, baseUrl: this.baseUrl, token: this.token, }); ``` ### Technical Analysis The `--file` option is documented as accepting URLs, but there are no restrictions on the network destination. The implementation does not block: - Loopback addresses such as `127.0.0.1` or `::1`. - RFC1918 private networks. - Link-local destinations such as `169.254.0.0/16`. - Cloud metadata services. - Reserved, multicast, or internal IPv6 ranges. - Hostnames that resolve to restricted addresses. - DNS rebinding. - Redirects from a public URL to a restricted destination. The request uses the host machine's network access. Therefore, a caller able to influence `--file` ca ...[truncated 1821 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/media.ts:253
Finding

Remote downloads are fully buffered before enforcing the size limit

Content
View full analysis
MAX_FILE_SIZE) { throw new Error( `file too large: ${buf.length} bytes (max ${MAX_FILE_SIZE / 1024 / 1024}MB)`, ); } ``` ### Technical Analysis `res.arrayBuffer()` reads the entire HTTP response into memory. Only after allocation and download completion does the implementation compare the resulting size to `MAX_FILE_SIZE`. Consequently, the declared 100 MB maximum does not constrain peak memory usage. An attacker-controlled server can return a response substantially larger than 100 MB, use chunked transfer encoding without a trustworthy `Content-Length`, or transmit data until the 60-second timeout. Depending on runtime memory limits and network speed, this can cause excessive garbage collection, process termination, or broader resource pressure. The timeout limits duration but not bytes received or memory allocated. ### Attack Path 1. An attacker supplies a URL under their control as the `--file` argument. 2. The server returns a very large response or continuously streams data. 3. `readFileOrUrl()` calls `res.arrayBuffer()` and accumulates the entire response in memory. 4. Memory consumption grows beyond the intended 100 MB limit. 5. The Node.js process may become unresponsive or terminate due to memory exhaustion. 6. The size check runs only if buffering completes successfully, too late to prevent resource consumption. ### Impact As ...[truncated 402 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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 (24)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description says this skill proactively sends WeChat messages and media/files. However, the supplied code chunk does not interact with WeChat, messaging APIs, files for transmission, users, or notification logic. It simply reads package.json and exports the version number. That is a materially different purpose from the declared behavior, so this is a clear mismatch.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file promotes sending text, images, video, and files through WeChat, which affects user data and transmits content to an external messaging service. While the README explains functionality, it does not clearly warn users that messages/files and related account data will be sent off-system to WeChat infrastructure.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest describes a narrowly scoped skill for proactively sending WeChat messages, but the README presents the skill as enabling recurring reminders, CI/deploy monitoring, SLA escalation, suspicious-login alerts, and metrics reporting. Those are broader automation/monitoring capabilities beyond message delivery itself, creating a mismatch between the claimed sending-focused scope and the documented behavior users are led to expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The README instructs users to place bot credentials in environment variables without any warning about secrecy, storage hygiene, or exposure risks. Tokens in shell history, logs, process listings, screenshots, or shared environment configurations can be stolen and then used to impersonate the bot and send messages or access the associated service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README promotes proactive WeChat messaging and arbitrary file/URL sending but does not warn that message contents and attached files may be transmitted to external services or recipients outside the local system. In an agent-driven workflow, this omission increases the risk of unintentionally exfiltrating sensitive data because users may ask the agent to send reports, images, or files without understanding the privacy implications.

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 · README.en.md (reported line 25)May include surrounding context.

md
安装/更新一个技能让你能主动给我发微信。

技能源码:https://github.com/lroolle/wxclawbot-cli
SKILL.md 在仓库根目录,把它放到 skills/wxclawbot-send/SKILL.md
CLI 依赖:npm install -g @claw-lab/wxclawbot-cli
如果你有 clawhub 可以直接:clawhub install wxclawbot-send

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

md
安装/更新一个技能让你能主动给我发微信。

技能源码:https://github.com/lroolle/wxclawbot-cli
SKILL.md 在仓库根目录,把它放到 skills/wxclawbot-send/SKILL.md
CLI 依赖:npm install -g @claw-lab/wxclawbot-cli
如果你有 clawhub 可以直接:clawhub install wxclawbot-send

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The CLI examples explicitly support sending local files and URLs, but the documentation omits any caution that local file contents or remote URL content will be delivered externally. Because this skill is designed for autonomous agent use, the lack of guardrails makes accidental disclosure of private documents, screenshots, reports, or internally hosted resources more likely.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill can access environment variables and perform outbound network actions via the documented CLI, but it does not declare any explicit tool scope or allowed-tools boundary. That creates an authorization gap where an agent may invoke networked behavior and consume sensitive env/config state without clear policy constraints, increasing the risk of unintended data exfiltration or message sending.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases are broad enough to match common user requests about messaging, increasing the chance the skill is auto-selected in contexts where the user did not specifically intend an external WeChat send. Because this skill performs outbound communication to third-party recipients, over-triggering can cause privacy leaks, unintended notifications, or accidental file transmission.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill enables proactive outbound messaging and file delivery to external WeChat recipients, but the description around usage does not prominently warn about the privacy and communication consequences. In agent settings, insufficient disclosure can lead to users unknowingly authorizing transmission of sensitive text, reports, or attachments outside the local environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The documentation explicitly describes the location and use of bot credentials and context tokens, but provides no warning that these values are sensitive secrets requiring protection. In a skill whose purpose is proactive WeChat messaging, exposure or mishandling of these files could let an attacker send unauthorized messages as the bot or abuse bound user context for message delivery.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The code accesses process.env.WXCLAW_TOKEN, which is a credential-like secret, but there is no confirmation prompt, logging, comment, or docstring in this file disclosing that the skill reads sensitive environment variables. Under the code-file criteria, access to sensitive environment variables should be flagged when no disclosure is present.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code reads local or remote file content and uploads it, then sends message payloads over HTTP using the configured token and recipient identifiers. In this file there is no confirmation prompt, print/log disclosure, or comment/docstring warning that user-provided text, file contents, and recipient metadata will be transmitted to an external service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The file performs authenticated POST requests to obtain an upload URL and then transmits encrypted media to a CDN using the provided bearer token, but there is no visible confirmation, user-facing logging, or warning text in the code. Because this sends user-provided content and metadata to external services, the behavior should be explicitly disclosed unless documented in accompanying markdown.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The function accepts arbitrary http/https URLs and fetches them server-side before uploading the resulting content to WeChat. In an agent skill that proactively sends media, this creates an SSRF/data-exfiltration primitive: a prompt or untrusted input can make the host retrieve internal resources or attacker-chosen content and relay it outward.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code reads arbitrary local files or downloads remote content and then other functions in the same file upload that data to external endpoints, but there is no confirmation prompt, user-facing log/print, or explanatory comment/docstring disclosing the behavior. For a code file, silent file access plus network transmission is a safety-relevant operation that should be visibly disclosed unless warned elsewhere.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The manifest describes sending text, images, video, and files to WeChat, which naturally suggests transmitting provided content. The README specifies that --file accepts not only local file paths but also URLs, implying the tool can fetch remote content as part of sending; that is an additional behavior not disclosed in the manifest description.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
71% confidence
Finding

The file presents activation guidance primarily in Chinese with some English equivalents, but it does not explicitly state whether users may interact in their preferred language or whether the language choice is optional. If organizational policy requires avoiding forced language constraints without opt-in, this should be clarified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The documentation discusses bot tokens and local account credential files without a clear handling warning, which can normalize unsafe treatment of secrets in prompts, logs, or shell history. If an agent exposes, copies, or mishandles these credentials, an attacker could abuse the bot account for unauthorized messaging or account access.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 43)May include surrounding context.

json
"proactive-messaging"
  ],
  "dependencies": {
    "commander": "^13.1.0"
  },
  "devDependencies": {
    "@types/node": "^25.5.0",

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 46)May include surrounding context.

json
"commander": "^13.1.0"
  },
  "devDependencies": {
    "@types/node": "^25.5.0",
    "tsx": "^4.21.0",
    "typescript": "^5.9.3"
  },

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 47)May include surrounding context.

json
},
  "devDependencies": {
    "@types/node": "^25.5.0",
    "tsx": "^4.21.0",
    "typescript": "^5.9.3"
  },
  "license": "MIT"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 48)May include surrounding context.

json
"devDependencies": {
    "@types/node": "^25.5.0",
    "tsx": "^4.21.0",
    "typescript": "^5.9.3"
  },
  "license": "MIT"
}

Static analysis

No suspicious patterns detected.