registry  /  weclaude  /  0.1.44

weclaude@0.1.44

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

LPM treats this as warn-only first-party agent extension lifecycle risk. The package is a Claude Code/WeCom bridge with broad agent-extension capabilities. Risk is lifecycle and control-surface exposure, but the confirmed mutation is first-party and mostly user-invoked rather than stealth install-time hijack.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
Global npm install may refresh an existing Claude marketplace; explicit `weclaude init` or `weclaude sync` activates plugin/settings/daemon setup.
Impact
Remote WeCom users authorized by config can approve tools and inject or mirror Claude sessions; misconfiguration could expose agent control.
Mechanism
First-party Claude plugin, MCP server, PreToolUse hook, local daemon, and WeCom websocket bridge
Rationale
Source inspection confirms dangerous AI-agent extension and remote-control capabilities, but the only install-time action is a guarded refresh of the package's own existing Claude marketplace, while initial broad setup is explicit user-command flow. This warrants warning for agent extension lifecycle risk, not a publish block.
Evidence
package.jsonscripts/postinstall.shdist/cli/init.jsdist/cli/sync.jshooks/hooks.jsonhooks/pre-tool-use.shdist/mcp/server.jsdist/daemon/index.jsdist/shared/paths.js~/.weclaude/config.jsonc~/.weclaude/secrets.json~/.weclaude/sync.lock.json~/.claude/settings.json~/.claude-internal/settings.json~/Library/LaunchAgents/com.weclaude.daemon.plist~/.config/systemd/user/weclaude.service
Network endpoints3
wss://openws.work.weixin.qq.com127.0.0.1:17890127.0.0.1:17890/approve

Decision evidence

public snapshot
AI called this Suspicious at 82.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • package.json has postinstall `sh scripts/postinstall.sh`.
  • scripts/postinstall.sh on global install runs `claude plugin marketplace update weclaude-local`.
  • dist/cli/init.js user command writes ~/.weclaude config/secrets, syncs Claude settings, installs plugin, and installs launchd/systemd daemon.
  • dist/cli/sync.js writes MCP/env entries into configured Claude settings.json targets.
  • hooks/pre-tool-use.sh registers a broad PreToolUse hook that forwards tool approvals to local daemon.
  • dist/daemon and dist/mcp expose remote-control flows that spawn/attach Claude/tmux sessions.
Evidence against
  • Postinstall is gated to global npm installs, requires `claude` on PATH, and only updates an existing named marketplace.
  • Initial plugin install and settings mutation occur via explicit `weclaude init` or `weclaude sync`, not automatic npm install.
  • Network use is package-aligned: WeCom websocket and localhost daemon endpoints.
  • No credential harvesting/exfiltration beyond user-entered WeCom bot credentials stored in ~/.weclaude/secrets.json.
  • No remote payload download/eval or obfuscated staged code found in inspected files.
  • dist/shared/paths.js invisible Unicode is an intentional regex for stripping zero-width chars, not Trojan Source control flow.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 31 file(s), 371 KB of source, external domains: 127.0.0.1, wwcdn.weixin.qq.com

Source & flagged code

10 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
82try { L83: const data = JSON.parse(readFileSync(persistPath, "utf8")); L84: const now = Date.now();
Low
Weak Crypto

Package source references weak cryptographic algorithms.

dist/daemon/session-cache.jsView on unpkg · L82
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 = 8637 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

cli/weclaude.shView on unpkg

Findings

2 Critical5 High6 Medium6 Low
CriticalTrojan Source Unicodedist/shared/paths.js
CriticalTrigger Reachable Dangerous Capabilitydist/shared/paths.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