Back to skill

Security audit

huo15-multi-wechat

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it advertises, but it can delete and modify macOS application bundles and has an argument-handling bug that can execute unintended shell commands.

Install only if you are comfortable with an agent modifying copied WeChat app bundles in /Applications, re-signing them with an ad-hoc signature, refreshing macOS Launch Services, and deleting old WeChat copy bundles. Do not pass untrusted or non-numeric copy counts, and review the script or patch count validation before running it.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/multi_wechat.sh:6
Finding

Unvalidated Count Argument Enables Shell Command Execution Through Arithmetic Expansion

Content
View full analysis
Remediation
View remediation
&2 exit 2 fi if (( 10#$COUNT > MAX_COUNT )); then echo "ERROR: count must not exceed $MAX_COUNT" >&2 exit 2 fi COUNT=$((10#$COUNT)) ``` The `10#` prefix forces decimal interpretation and avoids unintended octal behavior for values containing leading zeroes. The regular-expression check must occur before any arithmetic evaluation of the untrusted value. Replace `seq` command substitutions with native arithmetic loops after validation: ```bash for ((i = 2; i <= COUNT + 1; i++)); do # Existing loop body done ``` Apply the same change to all four loops currently located at lines 23, 46, 89, and 96. Additional hardening should include: 1. Reject zero, negative values, signs, whitespace, arithmetic operators, variable names, brackets, and command-substitution syntax. 2. Keep the maximum count low enough to prevent accidental disk exhaustion. 3. Check available disk space before copying application bundles. 4. Ensure any Agent invoking the script passes only a validated integer; this should supplement, not replace, script-side validation. 5. Avoid constructing privileged shell command strings. If privileged deletion remains necessary, pass only internally generated, strictly validated paths and quote each path safely. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (20)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill clearly instructs use of shell operations that copy, delete, modify app bundles, re-sign binaries, and refresh Launch Services, yet it declares no explicit tool scope or permission boundaries. In an agent environment, that mismatch can allow the skill to trigger powerful filesystem and execution actions without transparent user/admin review, increasing the risk of destructive or unauthorized system changes.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The activation aliases include broad phrases like “多个微信” that may appear in ordinary conversation, making accidental invocation more likely. Because this skill performs sensitive shell-backed system modifications on macOS applications, unintended activation could lead to app duplication, deletion of existing copies, or code-signing changes without the user explicitly intending to run such an invasive workflow.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The changelog documents behavior that modifies and re-signs a vendor application, changes bundle/executable identity, and forces Launch Services re-registration, but it provides no warning in this file about trust, compatibility, code-signing, or account-risk implications. In the context of a skill whose purpose is to bypass WeChat’s single-instance restrictions, omission of safety warnings increases the chance that users will run integrity-altering steps without understanding platform, app-policy, or support consequences.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

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

md
fi

# 获取原版 Bundle ID 和可执行文件名
ORIGINAL_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$ORIGINAL_APP/Contents/Info.plist")
ORIGINAL_EXEC=$(/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "$ORIGINAL_APP/Contents/Info.plist")
echo "Original WeChat: bundle ID=$ORIGINAL_BUNDLE_ID, executable=$ORIGINAL_EXEC"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/multi_wechat.sh (reported line 17)May include surrounding context.

sh
fi

# 获取原版 Bundle ID 和可执行文件名
ORIGINAL_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$ORIGINAL_APP/Contents/Info.plist")
ORIGINAL_EXEC=$(/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "$ORIGINAL_APP/Contents/Info.plist")
echo "Original WeChat: bundle ID=$ORIGINAL_BUNDLE_ID, executable=$ORIGINAL_EXEC"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/multi_wechat.sh (reported line 18)May include surrounding context.

sh
fi

# 获取原版 Bundle ID 和可执行文件名
ORIGINAL_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$ORIGINAL_APP/Contents/Info.plist")
ORIGINAL_EXEC=$(/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "$ORIGINAL_APP/Contents/Info.plist")
echo "Original WeChat: bundle ID=$ORIGINAL_BUNDLE_ID, executable=$ORIGINAL_EXEC"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/multi_wechat.sh (reported line 56)May include surrounding context.

sh
fi

# 获取原版 Bundle ID 和可执行文件名
ORIGINAL_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$ORIGINAL_APP/Contents/Info.plist")
ORIGINAL_EXEC=$(/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "$ORIGINAL_APP/Contents/Info.plist")
echo "Original WeChat: bundle ID=$ORIGINAL_BUNDLE_ID, executable=$ORIGINAL_EXEC"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/multi_wechat.sh (reported line 62)May include surrounding context.

sh
fi

# 获取原版 Bundle ID 和可执行文件名
ORIGINAL_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$ORIGINAL_APP/Contents/Info.plist")
ORIGINAL_EXEC=$(/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "$ORIGINAL_APP/Contents/Info.plist")
echo "Original WeChat: bundle ID=$ORIGINAL_BUNDLE_ID, executable=$ORIGINAL_EXEC"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/multi_wechat.sh (reported line 65)May include surrounding context.

sh
fi

# 获取原版 Bundle ID 和可执行文件名
ORIGINAL_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$ORIGINAL_APP/Contents/Info.plist")
ORIGINAL_EXEC=$(/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "$ORIGINAL_APP/Contents/Info.plist")
echo "Original WeChat: bundle ID=$ORIGINAL_BUNDLE_ID, executable=$ORIGINAL_EXEC"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/multi_wechat.sh (reported line 72)May include surrounding context.

sh
fi

# 获取原版 Bundle ID 和可执行文件名
ORIGINAL_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$ORIGINAL_APP/Contents/Info.plist")
ORIGINAL_EXEC=$(/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "$ORIGINAL_APP/Contents/Info.plist")
echo "Original WeChat: bundle ID=$ORIGINAL_BUNDLE_ID, executable=$ORIGINAL_EXEC"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/multi_wechat.sh (reported line 73)May include surrounding context.

sh
fi

# 获取原版 Bundle ID 和可执行文件名
ORIGINAL_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$ORIGINAL_APP/Contents/Info.plist")
ORIGINAL_EXEC=$(/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "$ORIGINAL_APP/Contents/Info.plist")
echo "Original WeChat: bundle ID=$ORIGINAL_BUNDLE_ID, executable=$ORIGINAL_EXEC"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/multi_wechat.sh (reported line 17)May include surrounding context.

sh
fi

# 获取原版 Bundle ID 和可执行文件名
ORIGINAL_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$ORIGINAL_APP/Contents/Info.plist")
ORIGINAL_EXEC=$(/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "$ORIGINAL_APP/Contents/Info.plist")
echo "Original WeChat: bundle ID=$ORIGINAL_BUNDLE_ID, executable=$ORIGINAL_EXEC"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/multi_wechat.sh (reported line 18)May include surrounding context.

sh
fi

# 获取原版 Bundle ID 和可执行文件名
ORIGINAL_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$ORIGINAL_APP/Contents/Info.plist")
ORIGINAL_EXEC=$(/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "$ORIGINAL_APP/Contents/Info.plist")
echo "Original WeChat: bundle ID=$ORIGINAL_BUNDLE_ID, executable=$ORIGINAL_EXEC"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/multi_wechat.sh (reported line 56)May include surrounding context.

sh
fi

# 获取原版 Bundle ID 和可执行文件名
ORIGINAL_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$ORIGINAL_APP/Contents/Info.plist")
ORIGINAL_EXEC=$(/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "$ORIGINAL_APP/Contents/Info.plist")
echo "Original WeChat: bundle ID=$ORIGINAL_BUNDLE_ID, executable=$ORIGINAL_EXEC"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/multi_wechat.sh (reported line 62)May include surrounding context.

sh
fi

# 获取原版 Bundle ID 和可执行文件名
ORIGINAL_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$ORIGINAL_APP/Contents/Info.plist")
ORIGINAL_EXEC=$(/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "$ORIGINAL_APP/Contents/Info.plist")
echo "Original WeChat: bundle ID=$ORIGINAL_BUNDLE_ID, executable=$ORIGINAL_EXEC"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/multi_wechat.sh (reported line 65)May include surrounding context.

sh
fi

# 获取原版 Bundle ID 和可执行文件名
ORIGINAL_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$ORIGINAL_APP/Contents/Info.plist")
ORIGINAL_EXEC=$(/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "$ORIGINAL_APP/Contents/Info.plist")
echo "Original WeChat: bundle ID=$ORIGINAL_BUNDLE_ID, executable=$ORIGINAL_EXEC"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/multi_wechat.sh (reported line 72)May include surrounding context.

sh
fi

# 获取原版 Bundle ID 和可执行文件名
ORIGINAL_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$ORIGINAL_APP/Contents/Info.plist")
ORIGINAL_EXEC=$(/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "$ORIGINAL_APP/Contents/Info.plist")
echo "Original WeChat: bundle ID=$ORIGINAL_BUNDLE_ID, executable=$ORIGINAL_EXEC"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/multi_wechat.sh (reported line 73)May include surrounding context.

sh
fi

# 获取原版 Bundle ID 和可执行文件名
ORIGINAL_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$ORIGINAL_APP/Contents/Info.plist")
ORIGINAL_EXEC=$(/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "$ORIGINAL_APP/Contents/Info.plist")
echo "Original WeChat: bundle ID=$ORIGINAL_BUNDLE_ID, executable=$ORIGINAL_EXEC"

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
89% confidence
Finding

The script collects root-owned app paths and passes them into an osascript 'do shell script ... with administrator privileges' call, which triggers privileged deletion. Even though the paths are internally generated, unnecessary privilege escalation increases risk and makes any path-handling mistake or future modification more dangerous because it would execute as admin.

Content

Scanner excerpt · scripts/multi_wechat.sh (reported line 28)May include surrounding context.

sh
if [ -d "$APP_PATH" ]; then
        OWNER=$(stat -f '%Su' "$APP_PATH" 2>/dev/null || echo "unknown")
        if [ "$OWNER" = "root" ]; then
            NEED_SUDO="$NEED_SUDO $APP_PATH"
        else
            rm -rf "$APP_PATH"
        fi

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script deletes existing /Applications/WeChatN.app bundles automatically with rm -rf, and escalates to administrator privileges for root-owned copies, without presenting the user a confirmation prompt or a safer rollback path. While the target path is constrained to a predictable naming pattern, this is still destructive behavior against application bundles and can cause unintended data loss or removal of locally modified app copies.

Content

No source excerpt is available for this finding.