Back to skill

Security audit

Wechat File Helper

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent WeChat automation purpose, but its scripts can send messages and transmit full browser screenshots containing login QR material without tight targeting, recipient validation, or per-action confirmation.

Review this skill carefully before installing. Only use it with a dedicated WeChat File Helper account and a private, verified QR delivery recipient. Avoid enabling the cron wrapper until the scripts are changed to target a specific WeChat tab, capture only the QR element, delete temporary QR files, validate recipients, and require confirmation before sending messages or screenshots.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/monitor.sh:10
Finding
Untargeted browser screenshot may disclose unrelated sensitive content<![CDATA[ ## Vulnerability Details **File Location**: `scripts/monitor.sh:10-12, 24-32`; `scripts/capture_qrcode.sh:7-14` **Vulnerability Type**: Unscoped browser capture and unintended data transmission **Risk Level**: High ### Vulnerable Code `scripts/monitor.sh:10-12, 24-32`: ```bash # Check if page is open PAGE_STATE=$(browser action=tabs targetUrl="$WEBSITE" 2>&1) if echo "$PAGE_STATE" | grep -q "_/\|chat\|message"; then echo "Logged in! Sending test message..." else echo "Not logged in - capturing QR..." # Capture QR browser action=screenshot path="$OUTPUT_FILE" # Send QR to user if [ -f "$OUTPUT_FILE" ]; then message action=send to="$USER_PHONE" media="$OUTPUT_FILE" echo "QR code sent to $USER_PHONE" else echo "Failed to capture QR" fi fi ``` `scripts/capture_qrcode.sh:7-14`: ```bash echo "Capturing QR code from filehelper.weixin.qq.com..." # Take screenshot browser action=screenshot path="$OUTPUT_FILE" if [ -f "$OUTPUT_FILE" ]; then echo "QR code captured: $OUTPUT_FILE" ls -la "$OUTPUT_FILE" ``` ### Technical Analysis The code queries tabs using the expected WeChat URL but does not extract, validate, or retain the `targetId` of the matching tab. The subsequent `browser action=screenshot` command is invoked without a `targetId` or an element selector. Consequently, the screenshot can be taken from the active or default browser context rather than the WeChat File Helper tab. In `monitor.sh`, the resulting image is then sent through a configured messaging channel. The script also does not verify the final page origin or confirm that the captured image contains a WeChat QR element before transmission. This behavior exceeds the minimum browser access necessary for the declared functionality. The Skill only needs to capture the QR element on a validated WeChat page, not the entire active browser context. ### Attack Path 1. The user or a scheduled job invokes `scripts/monitor.sh`. 2. A browser page other than ...[truncated 1073 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Extract the exact `targetId` returned for `https://filehelper.weixin.qq.com/`. 2. Pass that `targetId` explicitly to every screenshot, snapshot, evaluation, typing, and clicking operation. 3. Immediately before capture, verify that: - The origin is exactly `https://filehelper.weixin.qq.com`. - The page is in the expected logged-out state. - A unique QR-code element is present. 4. Capture only the validated QR-code element instead of the full browser viewport. 5. Abort if multiple matching tabs exist or if the target cannot be identified unambiguously. 6. Do not send an image merely because a file was created; validate that it came from the intended target and capture operation. 7. Require an explicitly configured and validated recipient before transmitting the image. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/monitor.sh:10
Finding
Untargeted browser actions can type and submit content on the wrong page<![CDATA[ ## Vulnerability Details **File Location**: `scripts/monitor.sh:10-21` **Vulnerability Type**: Unscoped browser automation and unsafe state detection **Risk Level**: Medium ### Vulnerable Code ```bash # Check if page is open PAGE_STATE=$(browser action=tabs targetUrl="$WEBSITE" 2>&1) if echo "$PAGE_STATE" | grep -q "_/\|chat\|message"; then echo "Logged in! Sending test message..." # Type message browser action=act request='{"kind":"type","ref":"input","text":"Hello from OpenClaw! 🦞"}' # Click send browser action=act request='{"kind":"click","ref":"send"}' echo "Message sent!" ``` ### Technical Analysis The script determines login state by applying a broad regular-expression match to the textual output of a tab query. Matches for `_`, `chat`, or `message` are not sufficient to prove that a specific WeChat File Helper page is authenticated. After this heuristic check, the script invokes browser actions without a `targetId`. The references `input` and `send` are generic and are not tied to a fresh snapshot from a validated WeChat tab. If another page is selected as the automation target and exposes compatible references, the fixed message may be typed and a button may be clicked there. The code also reports success without checking the resulting URL, page state, or a reliable send confirmation. ### Attack Path 1. A browser session contains a tab-query result matching `_`, `chat`, or `message`. 2. The heuristic classifies the session as logged in. 3. A different page is the active or default browser automation target. 4. That page has usable `input` and `send` references. 5. The script types `Hello from OpenClaw! 🦞` and activates the send control. 6. The unrelated page submits content or performs another action associated with that control. ### Impact Assessment The code uses the caller's existing authenticated browser privileges. It does not escalate system privileges, but it can cause unintended actions in authenticate ...[truncated 404 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse the tab-query response structurally instead of matching broad text fragments. 2. Require an exact origin and pathname match for the authenticated WeChat page. 3. Save the validated WeChat `targetId` and pass it to every browser action. 4. Take a new snapshot scoped to that target immediately before interacting with the page. 5. Resolve and validate selectors or references from that scoped snapshot rather than using generic hardcoded references. 6. Fail closed if the expected input or send button is missing or ambiguous. 7. Confirm successful transmission using a reliable page-specific indicator. 8. Remove the fixed test-message behavior from monitoring; only send user-supplied content following explicit authorization. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/capture_qrcode.sh:4
Finding
Sensitive login QR image is stored at a predictable and unmanaged temporary path<![CDATA[ ## Vulnerability Details **File Location**: `scripts/capture_qrcode.sh:4-14`; `scripts/monitor.sh:5, 24-32` **Vulnerability Type**: Unsafe temporary-file handling of authentication material **Risk Level**: Medium ### Vulnerable Code `scripts/capture_qrcode.sh:4-14`: ```bash OUTPUT_FILE="${1:-/tmp/wechat-qr.png}" # Use browser to capture screenshot echo "Capturing QR code from filehelper.weixin.qq.com..." # Take screenshot browser action=screenshot path="$OUTPUT_FILE" if [ -f "$OUTPUT_FILE" ]; then echo "QR code captured: $OUTPUT_FILE" ls -la "$OUTPUT_FILE" ``` `scripts/monitor.sh:5, 24-32`: ```bash OUTPUT_FILE="/tmp/wechat-qr.png" ``` ```bash echo "Not logged in - capturing QR..." # Capture QR browser action=screenshot path="$OUTPUT_FILE" # Send QR to user if [ -f "$OUTPUT_FILE" ]; then message action=send to="$USER_PHONE" media="$OUTPUT_FILE" ``` ### Technical Analysis A WeChat login QR is temporary authentication material. The scripts write it to the predictable shared path `/tmp/wechat-qr.png`, do not establish a restrictive `umask`, do not check for a pre-existing symbolic link or unexpected file type, and do not delete the file after use. The standalone capture helper also accepts an arbitrary caller-provided output path. The script does not constrain that path to a private temporary directory or reject an existing destination. The exact overwrite behavior depends on the browser screenshot tool, but the script itself provides no path-safety controls. The existence check verifies only that a regular file is present. It does not prove that the current operation securely created the file or that the file contains the intended QR image. ### Attack Path 1. A local process predicts or monitors `/tmp/wechat-qr.png`. 2. The Skill captures a fresh login QR at that location. 3. The image remains on disk after capture or delivery. 4. Another process with sufficient local file access reads the QR while it remains valid. ...[truncated 1170 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Set `umask 077` before creating any file containing authentication material. 2. Create a private temporary directory with `mktemp -d` and mode `0700`. 3. Generate a unique filename inside that directory rather than using a fixed path. 4. Reject symbolic links, existing files, and non-regular destinations. 5. Do not accept an arbitrary output path unless the feature is necessary. If retained, canonicalize and restrict it to an approved private directory. 6. Register a shell cleanup trap to remove the image and temporary directory on success, failure, interruption, and exit. 7. Delete the QR immediately after successful delivery. 8. Capture only the QR element to minimize the sensitive data stored in the file. 9. Verify that the file was created by the current capture operation before sending or reporting success. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/cron-wechat.sh:1
Finding
Cron-ready wrapper repeatedly executes outbound actions with inconsistent recipient handling<![CDATA[ ## Vulnerability Details **File Location**: `scripts/cron-wechat.sh:1-13`; `scripts/monitor.sh:6, 10-32`; `SKILL.md:249-263` **Vulnerability Type**: Unsafe recurring execution and configuration mismatch **Risk Level**: Medium ### Vulnerable Code `scripts/cron-wechat.sh:1-13`: ```bash #!/bin/bash # WeChat File Helper cron job - run every minute # Source monitor script SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/monitor.sh" # Run monitor # This will either: # 1. Send QR code if not logged in # 2. Send test message if logged in echo "$(date): Running WeChat File Helper check..." ``` `scripts/monitor.sh:6`: ```bash USER_PHONE="${1}" ``` `scripts/monitor.sh:14-32`: ```bash echo "Logged in! Sending test message..." # Type message browser action=act request='{"kind":"type","ref":"input","text":"Hello from OpenClaw! 🦞"}' # Click send browser action=act request='{"kind":"click","ref":"send"}' echo "Message sent!" else echo "Not logged in - capturing QR..." # Capture QR browser action=screenshot path="$OUTPUT_FILE" # Send QR to user if [ -f "$OUTPUT_FILE" ]; then message action=send to="$USER_PHONE" media="$OUTPUT_FILE" echo "QR code sent to $USER_PHONE" ``` The documented wrapper in `SKILL.md:249-263` instead describes an environment variable: ```bash #!/bin/bash # cron-wechat.sh - Run every minute via cron # Set owner phone for QR delivery OWNER_PHONE="${OWNER_PHONE:-+1234567890}" # Source main script SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/monitor.sh" # Log echo "$(date): WeChat File Helper check" ``` ### Technical Analysis Sourcing `monitor.sh` executes all of its top-level commands immediately. Therefore, each invocation of the cron wrapper performs a browser action and either attempts to send a fixed test message or captures and transmits a screenshot. The executable monitor reads the recipient from positional parameter `$1`, while the documentation ...[truncated 2146 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Execute the monitor as a separate process instead of sourcing a script with top-level side effects. 2. Use one documented recipient variable consistently, such as `OWNER_PHONE`. 3. Require the recipient to be explicitly configured and validate it before any capture or delivery. 4. Exit safely when the recipient is absent or malformed. 5. Add an inter-process lock to prevent overlapping scheduled executions. 6. Track state transitions and send a QR notification only when the login state changes or the prior QR expires. 7. Add duplicate suppression and a conservative rate limit. 8. Remove automatic fixed test-message sending from the monitoring workflow. 9. Require explicit operator consent before providing cron configuration. 10. Document how to disable and remove any manually installed cron entry. 11. Keep cron registration outside automatic installation; do not modify the user's crontab without a clear, separate confirmation step. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (6)

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill instructs the agent to capture a WeChat login QR code and send it through external channels such as WhatsApp, Telegram, or Slack without a prominent privacy and security warning. Login QR images are authentication artifacts; forwarding them to third-party messaging systems can expose account access to unintended recipients, channel compromise, retention policies, or logging by external services.

Session Persistence

Medium
Category
Rogue Agent
Content
| Wrong refs after reload | Page reload resets refs |
| QR not sending | Check configured channels |
| Messages not arriving | Verify recipient is correct |
| Cron not working | Check `crontab -e` entry |
| Browser not starting | Run `openclaw browser status` |

---
Confidence
85% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The script detects a logged-in state and then automatically types and sends a message through the browser without any runtime confirmation from the user. This grants the skill active impersonation capability in a messaging context, which could be abused to send unauthorized content, spam, or social-engineering messages from the user's account.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The screenshot is captured and transmitted externally with no clear disclosure of what data is being collected or sent, and screenshots can contain highly sensitive content beyond the intended QR code. In this context, the page relates to account login, so undisclosed capture and transfer increases the risk of credential exposure and privacy violations.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The script captures a browser screenshot containing a WeChat login QR code and sends it to an arbitrary phone number supplied as input, creating an exfiltration channel for sensitive authentication material. Because there is no validation, consent check, or documented business need for outbound transmission, this can leak account access data or other page contents to an external recipient.

Missing User Warnings

Low
Confidence
83% confidence
Finding
This code file performs shell execution by sourcing `monitor.sh`, but the file itself provides no user-facing disclosure beyond an internal comment. Under the stated criteria for code files, subprocess or shell execution should have some visible warning, logging, confirmation, or documented warning in accompanying markdown.

Static analysis

No suspicious patterns detected.