registry  /  weclaude  /  0.1.51

weclaude@0.1.51

Bridge Claude Code and WeCom: PreToolUse approval cards + bidirectional tmux session mirror with image paste

AI Security Review

scanned 3h ago · by lpm-firewall-ai

Review flagged AI-agent configuration or capability changes. This remains warn-only unless evidence shows foreign-agent hijack through preinstall/install/postinstall, hidden persistence, exfiltration, remote code execution, or other concrete malicious behavior.

Static reason
High-risk behavior combination matched malicious policy.; previous stored version diff introduced dangerous source
Trigger
User runs `weclaude init` or other explicit `weclaude` setup commands; global postinstall only refreshes an existing named marketplace.
Impact
An authorized WeCom bot/chat can approve tool actions and control configured local Claude sessions, creating meaningful agent-control risk if credentials or authorization are misconfigured.
Mechanism
WeCom WebSocket bridge with local MCP/hook integration and tmux Claude-session control.
Rationale
Source establishes a real, high-impact AI-agent remote-control capability and explicit user-controlled persistence/configuration. It does not establish covert exfiltration, remote payload execution, or malicious postinstall control-surface takeover.
Evidence
package.jsonscripts/postinstall.shscripts/install.shdist/cli/init.jsdist/cli/sync.jsdist/daemon/ws.jsdist/daemon/index.jshooks/pre-tool-use.shdist/shared/paths.jsdist/daemon/redact.js~/.weclaude/config.jsonc~/.weclaude/secrets.json~/.claude/settings.json~/.config/systemd/user/weclaude.service~/Library/LaunchAgents/com.weclaude.daemon.plist
Network endpoints2
wss://openws.work.weixin.qq.com127.0.0.1:17890

Decision evidence

public snapshot
AI called this Suspicious at 91.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for warning
  • `dist/cli/init.js` explicitly installs a Claude plugin, syncs MCP/env settings, and starts a resident daemon.
  • `dist/cli/sync.js` writes a managed `weclaude` MCP server and daemon environment values into configured agent settings.
  • `scripts/install.sh` persists `dist/daemon/index.js` as a user launchd/systemd service when explicitly invoked.
  • `dist/daemon/ws.js` connects using configured WeCom bot credentials; daemon routes expose session switching and tmux/Claude spawning.
  • `hooks/pre-tool-use.sh` sends Claude tool-use data to the local daemon for remote approval.
Evidence against
  • `scripts/postinstall.sh` is guarded to global installs with `claude` present and only updates the named `weclaude-local` marketplace.
  • No install hook writes arbitrary agent settings, installs the daemon, or executes a downloaded payload.
  • `dist/shared/paths.js` invisible Unicode is a documented sanitization regex, not concealed control flow.
  • Local hook/CLI endpoints use loopback `127.0.0.1`; no unrelated exfiltration endpoint was confirmed.
  • `dist/daemon/redact.js` redacts credential-shaped tool-input values before IM forwarding.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 36 file(s), 437 KB of source, external domains: 127.0.0.1, unpkg.com, wwcdn.weixin.qq.com

Source & flagged code

11 flagged · loading source
package.jsonView file
scripts.postinstall = sh scripts/postinstall.sh
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
scripts.postinstall = sh scripts/postinstall.sh
Medium
Ambiguous Install Lifecycle Script

Install-time lifecycle script is not statically allowlisted and needs review.

package.jsonView on unpkg
dist/mcp/server.jsView file
6import { StdioServerTransport } from "@[redacted].js"; L7: import { spawn } from "node:child_process"; L8: import { existsSync, readdirSync, statSync } from "node:fs";
High
Child Process

Package source references child process execution.

dist/mcp/server.jsView on unpkg · L6
6import { StdioServerTransport } from "@[redacted].js"; L7: import { spawn } from "node:child_process"; L8: import { existsSync, readdirSync, statSync } from "node:fs"; ... L11: import { z } from "zod"; L12: const DAEMON_BASE = process.env.WECLAUDE_DAEMON_BASE ?? "http://127.0.0.1:17890"; L13: const ok = (data) => ({
High
Same File Env Network Execution

A single source file combines environment access, network access, and code or shell execution; review context before blocking.

dist/mcp/server.jsView on unpkg · L6
dist/daemon/session-cache.jsView file
88try { L89: const data = JSON.parse(readFileSync(persistPath, "utf8")); L90: const now = Date.now();
Low
Weak Crypto

Package source references weak cryptographic algorithms.

dist/daemon/session-cache.jsView on unpkg · L88
dist/daemon/spawn-tmux.jsView file
25// before the first paste-buffer inject hits. L26: import { spawn } from "node:child_process"; L27: import { randomUUID } from "node:crypto"; ... L33: const augmentedPath = (orig) => { L34: const extras = [NODE_BIN_DIR, "/opt/homebrew/bin", "/usr/local/bin", `${process.env.HOME ?? ""}/.local/bin`].filter(Boolean); L35: const seen = new Set(); ... L48: let err = ""; L49: proc.stdout?.on("data", (c) => (out += c.toString("utf8"))); L50: proc.stderr?.on("data", (c) => (err += c.toString("utf8"))); ... L76: const claudeConfigCandidates = (claudeBin) => { L77: const home = homedir(); L78: const name = basename(claudeBin);
Medium
Install Persistence

Source writes installer persistence such as shell profile or service configuration.

dist/daemon/spawn-tmux.jsView on unpkg · L25
dist/shared/paths.jsView file
10contains invisible/control Unicode U+200B (zero width space) const INVISIBLE = /[<U+200B>-<U+200D><U+2060>-<U+FEFF>]/g;
Critical
Trojan Source Unicode

Source contains bidi control or invisible Unicode characters associated with Trojan Source attacks.

dist/shared/paths.jsView on unpkg · L10
Trigger-reachable chain: manifest.bin -> dist/cli/init.js -> dist/shared/paths.js Reachable file contains a blocking source-risk pattern.
Critical
Trigger Reachable Dangerous Capability

A package entrypoint or install-time lifecycle script reaches a source file with blocking dangerous behavior.

dist/shared/paths.jsView on unpkg
dist/cli/init.jsView file
61log(c.dim(" building...")); L62: const r = spawnSync("npx", ["tsc", "-p", "tsconfig.json"], { cwd: REPO, stdio: "inherit" }); L63: if (r.status !== 0)
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

dist/cli/init.jsView on unpkg · L61
cli/weclaude.shView file
path = cli/weclaude.sh kind = build_helper sizeBytes = 8928 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

cli/weclaude.shView on unpkg
dist/daemon/mirror-bridge.jsView file
matchType = previous_version_dangerous_delta matchedPackage = weclaude@0.1.48 matchedIdentity = npm:d2VjbGF1ZGU:0.1.48 similarity = 0.788 summary = stored previous version shares package body but lacks this dangerous source file
Critical
Previous Version Dangerous Delta

This package version adds a dangerous source file absent from the previous stored version; route for source-aware review.

dist/daemon/mirror-bridge.jsView on unpkg

Findings

3 Critical5 High6 Medium6 Low
CriticalTrojan Source Unicodedist/shared/paths.js
CriticalTrigger Reachable Dangerous Capabilitydist/shared/paths.js
CriticalPrevious Version Dangerous Deltadist/daemon/mirror-bridge.js
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processdist/mcp/server.js
HighShell
HighSame File Env Network Executiondist/mcp/server.js
HighRuntime Package Installdist/cli/init.js
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencedist/daemon/spawn-tmux.js
MediumShips Build Helpercli/weclaude.sh
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowWeak Cryptodist/daemon/session-cache.js
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings