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.
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.
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.
host: env.HOST ?? "0.0.0.0", port: Math.max(1, parseNumber(env.PORT, 8787)) ... sharedSecret: env.BRIDGE_SHARED_SECRET ?? "dev-bridge-secret"
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.
This is expected for a bridge, but misuse or weak authentication could cause unwanted WeChat replies or disruption of pending bridge commands.
The plugin exposes authenticated endpoints that manage sidecar command queues and administrative command flushing, which can influence the WeChat automation workflow.
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);Run the service only in a trusted environment, keep the shared secret private, restrict allowed clients, and review logs/admin actions when troubleshooting.
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.
The bridge stores local SQLite state and, by default, keeps raw WeChat message text, while raw mail body storage is disabled by default.
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)
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.
Email contents or one-time verification codes may be posted into a WeChat chat where all chat participants can see them.
Mail previews and extracted verification codes can be included in WeChat replies, which is the intended bridge behavior but crosses a sensitive data boundary.
lines.push(`内容:${truncate(result.bodyPreview, options.maxBodyPreviewChars)}`);
if (result.extractedFields?.code) {
lines.push(`验证码:${result.extractedFields.code}`);
}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.
The bundle may not build as-is, or users may be tempted to fetch missing code from outside the reviewed artifact set.
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.
import { SQLiteStore } from "./state/sqlite";Verify the complete release source and provenance before running or replacing missing files, especially for persistence and authentication components.
