Back to skill

Security audit

通过微信控制openclaw

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent WeChat gateway, but it exposes high-impact OpenClaw command access through weakly authenticated public message flows.

Review before installing or deploying. Use this only in a controlled environment unless you add authenticated webhook verification, remove fixed-phrase whitelist enrollment, disable or allowlist slash commands, require HTTPS for the API endpoint, redact logs, and avoid publicly serving retained user images. Run it under a dedicated low-privilege account with narrowly scoped OpenClaw credentials.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (5)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
main.py:960
Finding

Unauthenticated Webhook Enables Arbitrary OpenClaw CLI Invocation

Content
View full analysis
dict: sid = safe_session_id(session_id) parts = command_text[1:].strip().split() if command_text.startswith("/") else command_text.strip().split() if not parts: return {"ok": False, "reply": "❌ 空命令"} cmd = [self.bin] + parts logger.info("🛠️ [OpenClaw CMD] sid=%s | %s", sid, " ".join(cmd)) try: res = self._run_subprocess(cmd, self.cmd_timeout) ``` ```python if text.strip().startswith("/"): result = adapter.command(session_id, text.strip()) if not result.get("ok", False): logger.error("❌ OpenClaw 命令失败 sid=%s | err=%s", session_id, result.get("reply", "")) reply_text(to_wxid, "⚠️ 命令执行失败,请稍后重试。", config) return ``` ```python @app.post("/wechat/callback") async def handle_wechat(request: Request): try: config = load_config() body = await request.body() logger.info("📦 原始回调: %s", body.decode("utf-8", errors="ignore")) data = json.loads(body) parsed = parse_wechat_payload(data) ``` ### Technical Analysis The publicly exposed callback does not verify a signature, shared secret, timestamp, nonce, source address, or any other proof that a request originated from the legitimate WeChat API provider. Identity fields such as the sender and chat ID are trusted directly from the request body. Messages beginning with `/` are split into arguments and appended to the configured OpenC ...[truncated 1728 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
main.py:1000
Finding

Documented Fixed Phrase Allows Persistent Whitelist Self-Enrollment

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
main.py:167
Finding

API Token and WeChat Data Are Sent Through a Plaintext HTTP Endpoint

Content
View full analysis
bool: if not self.saved_app_id: return False try: logger.info("📡 正在检测微信在线状态...") res = requests.post( f"{self.base_url}/login/checkOnline", headers=self._headers(), json={"appId": self.saved_app_id}, timeout=10, proxies=NO_PROXY ) ``` ```python requests.post( f"{config['WX_BASE_URL']}/message/postText", headers={"VideosApi-token": config["WX_API_TOKEN"]}, json={ "appId": config["WX_APP_ID"], "toWxid": to_wxid, "content": text }, timeout=10, proxies=NO_PROXY ) ``` ### Technical Analysis The default API base URL uses unencrypted HTTP. Requests attach the API token to a header and transmit operational data such as the application ID, recipient identifiers, login UUIDs, response content, and image URLs. HTTP provides neither transport confidentiality nor authenticated server identity. A network-positioned attacker can inspect or modify requests and responses. Disabling proxies through `NO_PROXY` does not provide encryption and may bypass an organization's controlled egress inspection without reducing network interception risks. Transmission to the external service is functionally necessary for the gateway, but plaintext transport exceeds the minimum safe privilege and confidentiality requirements. ### Attack Path 1. Position an attacker on a shared network, compromised router, upstream provider p ...[truncated 807 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
main.py:960
Finding

Raw Callback Logging and Public Static Image Hosting Expose Sensitive Content

Content
View full analysis
Optional[str]: if not img_b64: return None try: padded = img_b64 + "=" * (-len(img_b64) % 4) img_bytes = base64.b64decode(padded) filename = f"incoming_{msg_id}_{int(time.time())}.jpg" file_path = os.path.join(IMG_DIR, filename) with open(file_path, "wb") as f: f.write(img_bytes) return filename ``` ```python body = await request.body() logger.info("📦 原始回调: %s", body.decode("utf-8", errors="ignore")) data = json.loads(body) ``` ```python if msg_type == 3: filename = save_incoming_image_from_base64(img_buffer_b64, msg_id) if not filename: reply_text(chat_id, "⚠️ 收到图片,但暂时无法解析图片数据。", config) return {"status": "image_save_failed"} local_path = os.path.join(IMG_DIR, filename) image_url = f"{config['PUBLIC_URL']}/images/{quote(filename)}" if config["PUBLIC_URL"] else "" ``` ### Technical Analysis Every raw callback body is written to a persistent log. Callback bodies can include private message text, account identifiers, metadata, and base64-encoded image content. No redaction or retention limit is applied in the code. Deco ...[truncated 1997 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
README.md:172
Finding

Runtime Dependencies Are Installed Without Version or Integrity Pinning

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (24)

Ssd 1

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documented whitelist mechanism allows any user to self-authorize by sending a fixed phrase asserting ownership, which is effectively no authentication at all. An attacker who knows or guesses the phrase can gain access to private-chat functionality, bypassing the intended whitelist protection and potentially reaching downstream agent or command features.

Content

No source excerpt is available for this finding.

Ssd 1

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The FAQ repeats the same bypass phrase, making the access-control weakness even easier to discover and exploit. Publishing a semantic privilege-escalation trigger in the documentation materially lowers attacker effort and undermines the claimed private-chat whitelist boundary.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
本 skill 附带一个可运行的单文件网关项目 `main.py`,主要能力包括:

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
本 skill 附带一个可运行的单文件网关项目 `main.py`,主要能力包括:

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
本 skill 附带一个可运行的单文件网关项目 `main.py`,主要能力包括:

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · main.py (reported line 373)May include surrounding context.

python
return hashlib.md5(raw.encode("utf-8")).hexdigest()

def build_subprocess_env() -> dict:
    env = os.environ.copy()
    for key in [
        "HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY",
        "http_proxy", "https_proxy", "all_proxy"

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The gateway forwards any slash-prefixed text to the OpenClaw binary as a command, exposing capabilities well beyond simple chat routing or image recognition. Because private-chat access can be self-granted via a magic phrase and group-triggered messages are user-controlled, untrusted WeChat users may reach privileged local agent commands with potentially dangerous side effects.

Content

No source excerpt is available for this finding.

Ssd 4

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Any private user who sends the phrase '我是你的主人' is automatically added to the whitelist, effectively self-authorizing as a trusted user with no prior verification. In this skill, that is especially dangerous because whitelisted users can then access command execution paths and other privileged bot behaviors.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README promotes private chat, group chat, image recognition, and OpenClaw integration without warning that message content may be forwarded to external processing components such as the OpenClaw CLI and third-party WeChat API service. Users and deployers may unknowingly transmit private conversations or group content to external systems, creating a meaningful confidentiality and compliance risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README explicitly says user images are saved, converted into URLs, and sent onward for analysis, but it does not mention retention limits, access controls, consent, or whether those URLs are publicly reachable. In a chat gateway handling potentially sensitive personal images, this creates a real privacy and data-exposure risk if operators deploy it as documented.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill advertises and describes capabilities that require environment access, writing configuration files, making network callbacks, and invoking the OpenClaw CLI, but it does not declare any explicit tool scope or permissions. This creates a transparency and least-privilege problem: users or platforms may execute a skill with broader powers than expected, increasing the chance of unintended network exposure, credential use, or shell execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill instructs users to configure a public callback URL and API token, but does not warn that this exposes an externally reachable webhook and sensitive credentials. In a gateway skill that receives chat messages and sends responses externally, missing this warning can lead to insecure deployment, accidental token leakage, or exposing a callback endpoint without proper validation and hardening.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
### 2. 微信 API 基础地址默认固定
当前默认使用:

`http://api.wechatapi.net/finder/v2/api`

一般不需要手动修改。

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation states that a private user can join the whitelist by sending a simple phrase, but it does not warn that this is effectively self-service authorization. In a messaging gateway, that lowers the barrier for unauthorized users to gain access to agent functionality and any downstream actions the agent can perform.

Content

No source excerpt is available for this finding.

Ssd 4

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

Allowing private-chat whitelist access to be granted by sending a trust phrase is an authentication bypass pattern: knowledge of a static string becomes sufficient to obtain trusted status. If discovered or guessed, an attacker can enroll themselves and then interact with the OpenClaw-connected agent, potentially reaching any connected tools or sensitive conversation context.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

The configuration template advertises an HTTP, not HTTPS, default base URL for the WeChat API. If used as-is, API tokens and message content could be intercepted or modified by a network attacker, compromising both confidentiality and integrity.

Content

Scanner excerpt · main.py (reported line 80)May include surrounding context.

python
[wechat]
# 你的微信 API 基础地址
# 示例:http://api.wechatapi.net/finder/v2/api
base_url = {base_url}

# 你的微信 API Token

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

The runtime defaults set the upstream API base_url to plain HTTP. This can expose authentication tokens, QR/login flows, and message traffic to man-in-the-middle interception or tampering, which is especially risky for a messaging gateway handling sensitive conversations.

Content

Scanner excerpt · main.py (reported line 167)May include surrounding context.

python
"""

DEFAULTS = {
    "base_url": "http://api.wechatapi.net/finder/v2/api",
    "api_token": "",
    "app_id": "",
    "public_url": "",

Tainted flow: 'region_id' from input (line 250, user input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · main.py (reported line 434)May include surrounding context.

python
def get_qr_and_login(self, region_id: str) -> bool:
        try:
            logger.info("📡 正在获取登录二维码...")
            res = requests.post(
                f"{self.base_url}/login/getLoginQrCode",
                headers=self._headers(),
                json={

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · main.py (reported line 570)May include surrounding context.

python
return
    logger.info("📤 [发送文本] TO=%s | %s", to_wxid, short_text(text))
    try:
        requests.post(
            f"{config['WX_BASE_URL']}/message/postText",
            headers={"VideosApi-token": config["WX_API_TOKEN"]},
            json={

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · main.py (reported line 595)May include surrounding context.

python
logger.info("🖼️ [发送图片] TO=%s | %s", to_wxid, img_url)

    try:
        resp = requests.post(
            f"{config['WX_BASE_URL']}/message/postImage",
            headers={
                "VideosApi-token": config["WX_API_TOKEN"],

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The webhook handler logs the full raw request body, which can include message contents, identifiers, and image-related metadata. If logs are accessed by operators, backup systems, or other processes, sensitive user data is exposed beyond the minimum needed to operate the gateway.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

For image messages, the code instructs OpenClaw to analyze a user-supplied image and explicitly provides both a local filesystem path and a public URL. This expands the agent's data access surface beyond merely receiving image content and may enable unintended local file access behavior or external fetching behavior depending on OpenClaw's tool capabilities.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Incoming images are decoded and written to disk in a web-served directory without any user notice or storage controls. This creates persistent local retention of potentially sensitive user content and increases exposure because the same directory is mounted for HTTP access.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The generated prompt for image analysis hard-codes '用中文回答', requiring Chinese output regardless of the user's language preference. This is a natural-language locale policy issue because the skill does not offer a language choice or document a justified region-specific constraint.

Content

No source excerpt is available for this finding.