Back to skill

Security audit

WeChat Moments Post

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims, but it can automatically publish to WeChat Moments and leaves broad desktop screenshots on disk, so users should review it carefully before installing.

Install only if you are comfortable with a skill controlling the Windows desktop, moving/clicking in WeChat, reading configured image and caption values from environment variables, and publishing without a final built-in confirmation. Close or hide sensitive desktop content before running it, review the image and caption yourself before the publish step, and clean the configured temp screenshot directory afterward.

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

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/relaunch_wechat_open_moments.py:36
Finding

Full-Desktop Screenshots Persist in a Predictable Temporary Directory

Content
View full analysis

Vulnerability Details

File Locations:

  • scripts/relaunch_wechat_open_moments.py:16-28,36
  • scripts/publish_with_caption_verify.py:18-28,123
  • scripts/click_publish_ocr.py:17-25,59

Vulnerability Type: Excessive desktop capture and persistent storage of potentially sensitive screen content
Risk Level: Medium

Complete Vulnerable Code Snippets:

scripts/relaunch_wechat_open_moments.py:16-28,34-38

python
TMP_DIR = Path(
    os.environ.get(
        "WECHAT_MOMENTS_TMP",
        str(Path(tempfile.gettempdir()) / "wechat_moments"),
    )
)
TMP_DIR.mkdir(parents=True, exist_ok=True)
SHOT = TMP_DIR / "relaunch_wechat_open_moments.png"

DEFAULT_WECHAT_EXE = r"C:\Program Files\Tencent\Weixin\Weixin.exe"
WECHAT_EXE = os.environ.get("WECHAT_EXE", DEFAULT_WECHAT_EXE)

def grab_ocr():
    ImageGrab.grab().save(str(SHOT))
    res, _ = engine(str(SHOT))
    return res or []

scripts/publish_with_caption_verify.py:18-28,123

python
TMP_DIR = Path(
    os.environ.get(
        "WECHAT_MOMENTS_TMP",
        str(Path(tempfile.gettempdir()) / "wechat_moments"),
    )
)
TMP_DIR.mkdir(parents=True, exist_ok=True)
crop_path = TMP_DIR / "compose_crop_now.png"

custom_keywords = [
    kw.strip()
    for kw in os.environ.get("WECHAT_MOMENTS_VERIFY", "").split(",")
    if kw.strip()
]

ImageGrab.grab().save(str(TMP_DIR / "after_publish_attempt.png"))

scripts/click_publish_ocr.py:17-25,59

python
TMP_DIR = Path(
    os.environ.get(
        "WECHAT_MOMENTS_TMP",
        str(Path(tempfile.gettempdir()) / "wechat_moments"),
    )
)
TMP_DIR.mkdir(parents=True, exist_ok=True)

ImageGrab.grab().save(str(TMP_DIR / "after_publish_click.png"))

Technical Analysis

ImageGrab.grab() without a bbox argument captures the entire desktop rather than only the WeChat Moments window required by the automation. This can include content from un ...[truncated 1965 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace every unrestricted ImageGrab.grab() call with a capture limited to the validated WeChat or Moments window:

    python
    screenshot = ImageGrab.grab(
        bbox=(w.left, w.top, w.left + w.width, w.top + w.height)
    )
    
  2. Avoid retaining OCR screenshots. Process captures in memory where supported, or delete temporary images immediately in a finally block:

    python
    try:
        screenshot.save(str(path))
        result, _ = engine(str(path))
    finally:
        path.unlink(missing_ok=True)
    
  3. Make diagnostic screenshot retention explicitly opt-in and disabled by default.

  4. Use a unique per-run directory created through secure temporary-file APIs instead of fixed filenames in a shared predictable directory.

  5. Apply access controls that limit screenshot access to the current user where the operating system and deployment model permit it.

  6. Add startup and shutdown cleanup for stale screenshots left by interrupted executions.

  7. Document that diagnostic images may contain sensitive information if an operator deliberately enables retention.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/publish_with_caption_verify.py:16
Finding

PyAutoGUI Emergency Stop Disabled During Irreversible Publishing Actions

Content
View full analysis

Vulnerability Details

File Locations:

  • scripts/publish_with_caption_verify.py:14-16
  • scripts/click_publish_ocr.py:13-15

Vulnerability Type: Unsafe GUI automation configuration
Risk Level: Low

Complete Vulnerable Code Snippets:

scripts/publish_with_caption_verify.py:14-16

python
user32 = ctypes.windll.user32
pyautogui.PAUSE = 0.2
pyautogui.FAILSAFE = False

scripts/click_publish_ocr.py:13-15

python
user32 = ctypes.windll.user32
pyautogui.PAUSE = 0.2
pyautogui.FAILSAFE = False

The affected scripts subsequently perform OCR-based publication clicks without applying an OCR confidence threshold:

scripts/publish_with_caption_verify.py:108-118

python
clicked_pub = False
for box, txt, score in (res3 or []):
    if "发表" in txt:
        xs = [b[0] for b in box]
        ys = [b[1] for b in box]
        x = w.left + int(sum(xs) / 4)
        y = w.top + int(sum(ys) / 4)
        pyautogui.click(x, y)
        clicked_pub = True
        print("CLICK_PUBLISH", x, y, flush=True)
        break

scripts/click_publish_ocr.py:45-54

python
clicked = False
for box, txt, score in (res or []):
    if "发表" in txt:
        x, y = center(box)
        px = w.left + x
        py = w.top + y
        pyautogui.click(px, py)
        clicked = True
        print("CLICK_PUBLISH", px, py, txt, score, flush=True)
        break

Technical Analysis

PyAutoGUI normally allows a user to abort automation by moving the pointer to a screen corner. Setting pyautogui.FAILSAFE = False removes this emergency interruption mechanism.

This is significant because the affected scripts perform an irreversible external action: publishing content to WeChat Moments. The publication target is selected through OCR text matching, but the loops do not require a minimum value for the returned OCR score. A stale screenshot, incorrect foreground window, ...[truncated 1688 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove pyautogui.FAILSAFE = False or explicitly keep it enabled:

    python
    pyautogui.FAILSAFE = True
    
  2. Require a suitable OCR confidence threshold before accepting a publish-button match:

    python
    if score >= 0.85 and txt.strip() == "发表":
        # Validate and click.
    
  3. Confirm that the Moments window is still foreground, visible, and has the expected bounds immediately before clicking.

  4. Restrict candidate OCR results to the expected publish-button region instead of accepting the first occurrence of the text anywhere in the window.

  5. Add a final user confirmation or a short cancellable countdown before the irreversible publication click.

  6. Provide an additional cancellation mechanism, such as a keyboard shortcut, KeyboardInterrupt handling, or a small stop window.

  7. Verify the post-publication UI state and clearly report uncertainty instead of treating the click alone as proof of successful publication.

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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (17)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The skill advertises an end-to-end posting workflow, but the referenced behavior appears to only relaunch/navigate WeChat and use OCR-driven UI automation not disclosed in the metadata. This mismatch is dangerous because operators may invoke the skill believing it performs a limited action, while it actually interacts with broader desktop UI state and hidden prompts.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill advertises an end-to-end posting workflow, but the referenced behavior appears to only relaunch/navigate WeChat and use OCR-driven UI automation not disclosed in the metadata. This mismatch is dangerous because operators may invoke the skill believing it performs a limited action, while it actually interacts with broader desktop UI state and hidden prompts.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The automation clicks the publish button directly once OCR identifies it, without an explicit user confirmation step or final preview check. Because posting to Moments is an externally visible, effectively irreversible action, mis-targeting, OCR error, or stale clipboard content could cause unintended publication of sensitive or embarrassing content.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script captures a full-screen screenshot after the publish attempt and writes it to disk, which is far broader than needed for a Moments-posting workflow. This can collect unrelated sensitive data from other applications, notifications, documents, chats, or credentials visible anywhere on the desktop.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill declares no explicit tool scope even though it clearly depends on environment variables and shell/script execution. In an agent setting, missing permission boundaries can allow the skill to run with broader-than-expected capabilities, increasing the chance of unintended command execution, file access, or UI automation against the local desktop.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest description says to use the skill when asked to "publish/补发朋友圈、上传图片到朋友圈、在电脑端微信发朋友圈或需要稳定的朋友圈发布工作流." Several of these activation phrases are broad natural-language requests rather than a narrowly scoped invocation rule, and the file does not provide exclusion conditions or negative examples. This can make it unclear when the skill should activate versus when a user may only be discussing WeChat posting in general.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script automatically clicks the OCR-detected "发表" publish control and does so without any final user confirmation, dry-run mode, or validation that the window state and content are correct. Because posting to WeChat Moments is an externally visible and effectively irreversible action, OCR mistakes, window mis-targeting, or misuse by an upstream agent can cause unintended public disclosure or accidental publication.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script depends on Chinese strings such as the default caption and OCR matches for UI elements like "这一刻", "朋友圈", and "发表", which effectively forces use in a Chinese locale. There is no opt-in, alternate language handling, or clear documentation that the skill only works with the Chinese WeChat interface.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script captures and saves screenshots of the WeChat Moments window to disk for OCR-based UI targeting and verification. Even if intended for automation, persisting screen contents can expose private messages, contact names, images, and other sensitive on-screen data beyond what is necessary for posting, especially because the files are written to a temp directory.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill captures and stores screenshots of the user's screen/window without any built-in disclosure or consent flow in the script itself. In a desktop automation context, silent screen capture increases privacy risk because users may not expect image persistence during a simple posting workflow.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The function captures the entire screen and saves it to disk for OCR, which can collect unrelated sensitive information such as messages, credentials, personal data, or other application contents. Because this is an automation skill for social posting, broad screen capture is more dangerous than necessary and creates avoidable privacy exposure both in memory and on disk.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/relaunch_wechat_open_moments.py (reported line 74)May include surrounding context.

python
# launch fresh
subprocess.Popen([WECHAT_EXE])
print("LAUNCHED", WECHAT_EXE)
time.sleep(3)

Tainted flow: 'WECHAT_EXE' from os.environ.get (line 27, credential/environment) → subprocess.Popen (code execution)

Medium
Category
Data Flow
Confidence
96% confidence
Finding

The executable path is sourced from the WECHAT_EXE environment variable and then executed without verifying that it is actually the trusted WeChat binary. Any attacker or untrusted wrapper that can set the environment for this skill can cause arbitrary program execution under the user's account, which is especially relevant because this skill is designed to launch desktop software automatically.

Content

Scanner excerpt · scripts/relaunch_wechat_open_moments.py (reported line 74)May include surrounding context.

python
# launch fresh
subprocess.Popen([WECHAT_EXE])
print("LAUNCHED", WECHAT_EXE)
time.sleep(3)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This script repeatedly sends blind mouse clicks into another application's window to discover a publish control, without validating UI state or obtaining an explicit user confirmation at the moment of action. That is dangerous because mis-targeted clicks can trigger unintended actions in WeChat or a different foreground window, resulting in accidental posting, file selection, privacy exposure, or other unintended state changes.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The manifest describes a Windows desktop workflow for posting to WeChat Moments by opening the UI, selecting an image, pasting a caption, and publishing. Reading WECHAT_MOMENTS_CAPTION from the environment is not part of that stated GUI interaction flow and gives the skill a capability to consume process-level external data that is not justified by the description.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The click_text function and later pyautogui.click calls automatically interact with the desktop UI and can trigger actions inside WeChat. While some click events are logged after execution, there is no upfront warning or confirmation that the script will control the mouse and interact with another application window.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script trusts the WECHAT_MOMENTS_IMAGE environment variable as the source of the file to upload and performs only an existence check before injecting that path into the native file picker. In an automation skill that publishes to WeChat Moments, this can cause unintended or attacker-influenced local files to be posted if the environment is manipulated upstream, with no user confirmation or path restriction.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.