Back to skill

Security audit

Wecom Add Friend

Security checks for vulnerabilities and agentic risk

Overview

This WeCom bulk-add skill needs review because setup can send an undisclosed friend request to a hard-coded number and the automation may type or click in the wrong app.

Before installing, understand that this can operate your logged-in WeCom desktop client and send real friend requests. Do not use it on a primary account unless the setup flow is changed to be side-effect-free, window targeting fails closed, saved coordinates are revalidated, and every outbound request requires explicit confirmation.

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

T09 · Insecure Skill Coding Practices

Warning
Location
bin/wecom_auto_add.py:189
Finding

Calibration workflow sends a real friend request to a hard-coded phone number

Content
View full analysis

Vulnerability Details

File Location: bin/wecom_auto_add.py:189-218
Vulnerability Type: Unsafe external side effect during setup
Risk Level: Medium

Vulnerable Code

python
print("\nSTEP 7: Enter test phone number")
test_phone = "18655104861"  # 测试手机号
print(f"Entering test phone number: {test_phone}")
pyautogui.write(test_phone)
time.sleep(1)

print("\nSTEP 8: Press Enter to search")
print("The script will press Enter to search for the phone number")
pyautogui.press('enter')
time.sleep(3)  # 等待搜索结果

print("\nSTEP 9: Position for '添加' button")
print("Move mouse to the '添加' (Add) button in the search results")

input("Press ENTER when mouse is over '添加' button...")
add_button_pos = pyautogui.position()
print(f"✓ Add button position recorded: {add_button_pos}")

print("\nSTEP 10: Now click '添加'")
pyautogui.click(add_button_pos)
time.sleep(2)

print("\nSTEP 11: Position for '发送' button")
print("Move mouse to the '发送' (Send) button in the confirmation dialog")

input("Press ENTER when mouse is over '发送' button...")
send_button_pos = pyautogui.position()
print(f"✓ Send button position recorded: {send_button_pos}")

print("\nSTEP 12: Now click '发送'")
pyautogui.click(send_button_pos)
time.sleep(2)

Technical Analysis

The documented setup procedure in SKILL.md:50-55 presents --setup as a coordinate-recording operation. The implementation, however, searches for a hard-coded phone number and clicks both the Add and Send controls. This causes an externally visible account action while the user reasonably expects a local calibration process.

Although the terminal prompts describe individual clicks, the setup workflow does not clearly establish that the hard-coded number belongs to the user, identify its owner, or obtain explicit consent immediately before transmitting a real friend request. Coordinate calibration does not require submission of a live request, so this side ...[truncated 1327 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove all hard-coded real phone numbers from the calibration workflow.
  • Record pointer positions without clicking controls that submit external actions.
  • Use a screenshot, mock interface, or non-submitting UI state for calibration.
  • If a live account is genuinely required, require the user to supply and verify a number they control.
  • Display an explicit confirmation immediately before any friend request is sent, including the exact recipient and the fact that the action is externally visible.
  • Provide a dry-run mode that records and validates coordinates without sending keyboard input or mouse clicks.
  • Update SKILL.md to describe every externally visible side effect of setup.

T09 · Insecure Skill Coding Practices

Error
Location
bin/wecom_auto_add.py:93
Finding

Failure to identify WeCom causes automation to control an arbitrary visible window

Content
View full analysis

Vulnerability Details

File Location: bin/wecom_auto_add.py:93-103
Vulnerability Type: Unsafe GUI target fallback
Risk Level: High

Vulnerable Code

python
# If not found by title, try to find by process
if not wx_window:
    print("[INFO] Not found by title, trying process-based detection...")
    # We'll use the first non-minimized window as fallback
    for window in all_windows:
        if not window.isMinimized and window.visible:
            wx_window = window
            print(f"[INFO] Selected window: {window.title}")
            break

The selected window is subsequently activated:

python
if wx_window:
    # 激活窗口
    if wx_window.isMinimized:
        wx_window.restore()
    wx_window.activate()
    time.sleep(1)

Later, the script sends untrusted GUI input to the active window:

python
pyautogui.write(phone_number)
time.sleep(1)

pyautogui.press('enter')
time.sleep(3)

It may also invoke fixed-coordinate or Enter-key fallbacks:

python
else:
    # Press Enter to add (fallback)
    print("Using Enter key to add (fallback)")
    pyautogui.press('enter')
time.sleep(2)

else:
    # Press Enter to send (fallback)
    print("Using Enter key to send (fallback)")
    pyautogui.press('enter')

Technical Analysis

The fallback is described as process-based detection, but it does not inspect the owning process. Instead, it chooses the first visible, non-minimized window returned by pygetwindow. There is no verification that the selected window belongs to WXWork.exe.

The rest of the program assumes that this window is WeCom and performs keyboard entry, Enter presses, and coordinate-based clicks. Because GUI focus and window enumeration can change, these inputs may reach a browser, terminal, password manager, messaging client, administrative console, or another application.

The fixed-coordinate and Enter-key fallbac ...[truncated 1826 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove the arbitrary visible-window fallback and fail closed if WeCom cannot be positively identified.
  • Verify the window's owning process ID and executable path against the expected WXWork.exe installation before activation.
  • Revalidate the process identity, title, and expected UI state immediately before every input sequence.
  • Do not continue after navigation, coordinate loading, or control detection fails.
  • Eliminate fixed screen-coordinate and unconditional Enter-key submission fallbacks.
  • Prefer an accessibility or UI-automation API that identifies controls by application, window, role, and label rather than absolute coordinates.
  • Require a final preview and explicit user confirmation before sending any friend request.
  • Add a dry-run mode that reports the selected process, window, and intended controls without interacting with them.
  • Constrain phone input to validated phone-number syntax and avoid typing sensitive data until the intended input control has been verified.
Vulnerability Patterns
  • 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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (13)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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 · bin/wecom_auto_add.py (reported line 25)May include surrounding context.

python
"""Check if WeChat Work is running"""
    print("Checking WeChat Work status...")
    try:
        output = subprocess.check_output("tasklist | findstr WXWork.exe", shell=True)
        if b"WXWork.exe" in output:
            print("[OK] WeChat Work is running")
            return True

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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 · bin/wecom_auto_add.py (reported line 41)May include surrounding context.

python
print("Starting WeChat Work...")
    try:
        if os.path.exists(WXWORK_PATH):
            subprocess.Popen(WXWORK_PATH, shell=True)
            print(f"[OK] WeChat Work started from: {WXWORK_PATH}")
            # 等待企业微信启动
            print("Waiting for WeChat Work to initialize...")

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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 · bin/wecom_auto_add.py (reported line 41)May include surrounding context.

python
print("Starting WeChat Work...")
    try:
        if os.path.exists(WXWORK_PATH):
            subprocess.Popen(WXWORK_PATH, shell=True)
            print(f"[OK] WeChat Work started from: {WXWORK_PATH}")
            # 等待企业微信启动
            print("Waiting for WeChat Work to initialize...")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill invokes a local Python script via shell and relies on file access, but it declares no explicit tool or permission scope. That creates an authorization gap where an agent may execute impactful local automation without clear user-visible boundaries or least-privilege controls, increasing the chance of unintended execution or misuse.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Although the skill mentions adding friends, it does not prominently warn that invoking it will perform bulk automated contact additions in a live desktop client. Users may not appreciate that this is active UI automation with external side effects, making accidental or uninformed execution more likely.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The invocation examples include broad natural-language phrases such as '帮我加几个企业微信好友' and '批量加人' that could match ordinary conversation and trigger automation unexpectedly. In this skill's context, misfire is more dangerous because execution causes real outbound contact-add actions in a desktop client, potentially leading to spam, privacy issues, or account/platform penalties.

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 · bin/wecom_auto_add.py (reported line 25)May include surrounding context.

python
"""Check if WeChat Work is running"""
    print("Checking WeChat Work status...")
    try:
        output = subprocess.check_output("tasklist | findstr WXWork.exe", shell=True)
        if b"WXWork.exe" in output:
            print("[OK] WeChat Work is running")
            return True

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 · bin/wecom_auto_add.py (reported line 41)May include surrounding context.

python
print("Starting WeChat Work...")
    try:
        if os.path.exists(WXWORK_PATH):
            subprocess.Popen(WXWORK_PATH, shell=True)
            print(f"[OK] WeChat Work started from: {WXWORK_PATH}")
            # 等待企业微信启动
            print("Waiting for WeChat Work to initialize...")

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

If title matching fails, the code falls back to selecting the first visible non-minimized window and then sends clicks and keystrokes to it. In a GUI automation tool, this can direct friend-add actions, typed phone numbers, Enter presses, and other input into an unrelated application, causing unintended actions or data disclosure.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The setup flow does more than record coordinates: it submits real searches and sends an actual friend request to a hard-coded phone number during calibration. This creates unauthorized outbound actions during what appears to be a benign setup step, which is especially risky in an automation skill that users may run without scrutinizing every side effect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

When saved coordinates exist, the script automatically navigates and clicks through the GUI without fresh disclosure or confirmation that those coordinates still map to the intended controls. In GUI automation, stale or misaligned coordinates can trigger unintended submissions or interact with the wrong UI elements without operator awareness.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

After a short countdown, the script proceeds directly into automated friend-request sending without an explicit yes/no confirmation from the user. Because the skill performs actions on a real account and external recipients, accidental invocation or misunderstanding can cause unauthorized outreach at scale.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The inline comment says the code will 'try to find by process', but the actual fallback does not inspect processes and instead selects the first visible, non-minimized window. This documentation actively misdescribes the targeting logic in a way that obscures that the skill may automate the wrong application.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.