WeChat Mail Bridge (Windows/OpenClaw)

SuspiciousAudited by ClawScan on May 10, 2026.

Overview

The skill mostly matches its WeChat-to-mail bridge purpose, but it needs review because its HTTP control plane uses a known default shared secret while handling sensitive WeChat and mail data.

Before installing, plan to harden the deployment: set strong bridge and webhook secrets, bind the service to localhost unless remote sidecars are required, restrict which WeChat groups can use it, protect the SQLite state database, and verify the complete source/scripts before running the bundle.

Findings (5)

Artifact-based informational review of SKILL.md, metadata, install specs, static scan signals, and capability signals. ClawScan does not execute the skill or run runtime probes.

What this means

If the default secret is left unchanged and the port is reachable, another local or network user could authenticate to bridge endpoints and affect WeChat/mail bridge behavior.

Why it was flagged

The bridge control plane listens on all interfaces by default and uses a known default shared secret if the user does not set BRIDGE_SHARED_SECRET.

Skill content
host: env.HOST ?? "0.0.0.0",
port: Math.max(1, parseNumber(env.PORT, 8787))
...
sharedSecret: env.BRIDGE_SHARED_SECRET ?? "dev-bridge-secret"
Recommendation

Require users to set a strong unique BRIDGE_SHARED_SECRET and BHMAILER_WEBHOOK_SECRET, bind HOST to 127.0.0.1 unless remote access is truly needed, and protect the port with a firewall.

What this means

This is expected for a bridge, but misuse or weak authentication could cause unwanted WeChat replies or disruption of pending bridge commands.

Why it was flagged

The plugin exposes authenticated endpoints that manage sidecar command queues and administrative command flushing, which can influence the WeChat automation workflow.

Skill content
app.post("/api/v1/sidecar/commands/claim" ... const commands = deps.coordinator.claimCommands(body.sidecarId, body.limit ?? 10);
...
app.post("/api/v1/admin/commands/flush" ... const flushed = deps.coordinator.flushPendingCommands(body.reason);
Recommendation

Run the service only in a trusted environment, keep the shared secret private, restrict allowed clients, and review logs/admin actions when troubleshooting.

What this means

WeChat command text and bridge state may remain on disk and be visible to local users, backups, or anyone with access to the state database.

Why it was flagged

The bridge stores local SQLite state and, by default, keeps raw WeChat message text, while raw mail body storage is disabled by default.

Skill content
sqlitePath: env.SQLITE_PATH ?? path.resolve(process.cwd(), "state", "wechat-mail-bridge.db")
...
storeRawWechatText: parseBoolean(env.PRIVACY_STORE_RAW_WECHAT_TEXT, true),
storeRawMailBody: parseBoolean(env.PRIVACY_STORE_RAW_MAIL_BODY, false)
Recommendation

Place the SQLite database in a protected directory, reduce retention if possible, and set PRIVACY_STORE_RAW_WECHAT_TEXT=false if raw chat text does not need to be retained.

What this means

Email contents or one-time verification codes may be posted into a WeChat chat where all chat participants can see them.

Why it was flagged

Mail previews and extracted verification codes can be included in WeChat replies, which is the intended bridge behavior but crosses a sensitive data boundary.

Skill content
lines.push(`内容:${truncate(result.bodyPreview, options.maxBodyPreviewChars)}`);
if (result.extractedFields?.code) {
  lines.push(`验证码:${result.extractedFields.code}`);
}
Recommendation

Use this only with trusted chats, configure group allowlists, keep reply previews short, and avoid using it for accounts where OTP exposure would be unacceptable.

What this means

The bundle may not build as-is, or users may be tempted to fetch missing code from outside the reviewed artifact set.

Why it was flagged

The provided manifest does not list a matching bundle/plugin/src/state/sqlite.ts file, so the reviewed source tree appears incomplete around the persistence layer.

Skill content
import { SQLiteStore } from "./state/sqlite";
Recommendation

Verify the complete release source and provenance before running or replacing missing files, especially for persistence and authentication components.