registry  /  claude-codex-wechat  /  0.1.31

claude-codex-wechat@0.1.31

`claude-codex-wechat` 是一个本地 bridge daemon。它把:

AI Security Review

scanned 10h ago · by lpm-firewall-ai

The package exposes a WeChat/web/relay bridge that can drive local Claude or Codex agents with permissions disabled. It also mutates native Claude/Codex session state and can install a persistent user service when the CLI is started.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
running claude-codex-wechat start or the default CLI command, then receiving bridge messages
Impact
Remote WeChat/relay inputs can cause local AI agents to execute commands or edit files without normal approval prompts.
Mechanism
remote agent bridge with permission bypass and persistent daemon
Attack narrative
After the user starts the CLI, it installs/runs a background bridge daemon, listens on local/LAN interfaces, may connect to a relay, and forwards WeChat messages into Claude/Codex. The launched agents are configured with skipped permissions, disabled sandboxing, and automatic approval handlers, while session files are rewritten to preserve bypass-permission resume behavior.
Rationale
This is not install-time malware, but the runtime package deliberately creates a remotely reachable AI-agent control path with normal approval/sandbox protections disabled and persistent service setup. That is concrete dangerous agent control behavior rather than a mere scanner false positive.
Evidence
package.jsondist/server/cli.jsdist/mcp/mediaServer.jsREADME.mdconfig.example.json~/.claude-codex-wechat/config.json~/.claude-codex-wechat/mcp-media.json~/.claude/projects/*/*.jsonl~/.claude/history.jsonl~/.codex/session_index.jsonl~/.codex/state_5.sqlite~/Library/LaunchAgents/com.claude-codex-wechat.plist~/.config/systemd/user/claude-codex-wechat.service
Network endpoints4
ilinkai.weixin.qq.comwss://wechat.style520.com/agentnovac2c.cdn.weixin.qq.com/c2cregistry.npmmirror.com/claude-codex-wechat/latest

Decision evidence

public snapshot
AI called this Malicious at 92.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for block
  • dist/server/cli.js starts Claude with --dangerously-skip-permissions and package MCP config
  • dist/server/cli.js starts Codex app-server with sandboxPolicy disabled and approvalMode never
  • dist/server/cli.js registers approval handlers that always return approve for Codex command/file changes
  • dist/server/cli.js listens on 0.0.0.0:8787 and can start a relay tunnel to wss://wechat.style520.com/agent
  • dist/server/cli.js rewrites Claude session JSONL to add permissionMode bypassPermissions
  • dist/server/cli.js installs persistent launchd/systemd-user service on user-invoked default start
Evidence against
  • package.json has no install/postinstall hook; prepublishOnly is publish-time only
  • network endpoints are aligned with stated WeChat bridge functionality
  • writes primarily use ~/.claude-codex-wechat plus Claude/Codex session metadata
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsMinifiedUrlStrings
Manifest
NoLicenseWildcardDependency
scanned 3 file(s), 464 KB of source, external domains: 127.0.0.1, ilinkai.weixin.qq.com, novac2c.cdn.weixin.qq.com, react.dev, registry.npmmirror.com, www.apple.com, www.w3.org

Source & flagged code

7 flagged · loading source
dist/server/cli.jsView file
22// src/channels/weixin-direct/loginClient.ts L23: var DEFAULT_BASE_URL = "https://ilinkai.weixin.qq.com"; L24: var WeixinDirectLoginClient = class { ... L61: if (!response.ok) throw new Error(`weixin_login_request_failed:${response.status}`); L62: const payload = await response.json(); L63: return payload.data ?? payload; ... L71: function defaultConfigPath() { L72: return join(homedir(), ".claude-codex-wechat", "config.json"); L73: } L74: function loadBridgeConfig(path = process.env.BRIDGE_CONFIG ?? defaultConfigPath()) { L75: if (!existsSync(path)) return normalizeBridgeConfig({}, process.env, path); ... L170: function isRetriableRenameError(error) {
Critical
Remote Asset Decode Execute

Source fetches a remote non-code asset, decodes its contents, and dynamically executes the decoded payload.

dist/server/cli.jsView on unpkg · L22
Trigger-reachable chain: manifest.bin -> dist/server/cli.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/server/cli.jsView on unpkg
2762// src/providers/claude-code/claudeStreamingRunner.ts L2763: import { spawn as spawn3 } from "node:child_process"; L2764: import { randomUUID as randomUUID2 } from "node:crypto";
High
Child Process

Package source references child process execution.

dist/server/cli.jsView on unpkg · L2762
22Detached bundled service listener: dist/server/cli.js launches a Node helper and exposes a broad-bound HTTP listener. L22: // src/channels/weixin-direct/loginClient.ts L23: var DEFAULT_BASE_URL = "https://ilinkai.weixin.qq.com"; L24: var WeixinDirectLoginClient = class { ... L61: if (!response.ok) throw new Error(`weixin_login_request_failed:${response.status}`); L62: const payload = await response.json(); L63: return payload.data ?? payload; ... L71: function defaultConfigPath() { L72: return join(homedir(), ".claude-codex-wechat", "config.json"); L73: } L74: function loadBridgeConfig(path = process.env.BRIDGE_CONFIG ?? defaultConfigPath()) { L75: if (!existsSync(path)) return normalizeBridgeConfig({}, process.env, path); ... L170: function isRetriableRenameError(error) {
High
Spawned Bundled Service Listener

Source launches a detached bundled service that exposes a broad-bound HTTP listener.

dist/server/cli.jsView on unpkg · L22
22// src/channels/weixin-direct/loginClient.ts L23: var DEFAULT_BASE_URL = "https://ilinkai.weixin.qq.com"; L24: var WeixinDirectLoginClient = class { ... L61: if (!response.ok) throw new Error(`weixin_login_request_failed:${response.status}`); L62: const payload = await response.json(); L63: return payload.data ?? payload; ... L71: function defaultConfigPath() { L72: return join(homedir(), ".claude-codex-wechat", "config.json"); L73: } L74: function loadBridgeConfig(path = process.env.BRIDGE_CONFIG ?? defaultConfigPath()) { L75: if (!existsSync(path)) return normalizeBridgeConfig({}, process.env, path); ... L170: function isRetriableRenameError(error) {
Medium
Install Persistence

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

dist/server/cli.jsView on unpkg · L22
22// src/channels/weixin-direct/loginClient.ts L23: var DEFAULT_BASE_URL = "https://ilinkai.weixin.qq.com"; L24: var WeixinDirectLoginClient = class { ... L61: if (!response.ok) throw new Error(`weixin_login_request_failed:${response.status}`); L62: const payload = await response.json(); L63: return payload.data ?? payload; ... L71: function defaultConfigPath() { L72: return join(homedir(), ".claude-codex-wechat", "config.json"); L73: } L74: function loadBridgeConfig(path = process.env.BRIDGE_CONFIG ?? defaultConfigPath()) { L75: if (!existsSync(path)) return normalizeBridgeConfig({}, process.env, path); ... L170: function isRetriableRenameError(error) {
Low
Weak Crypto

Package source references weak cryptographic algorithms.

dist/server/cli.jsView on unpkg · L22
dist/web/assets/bootstrap-icons-mSm7cUeB.woff2View file
path = dist/web/assets/bootstrap-icons-mSm7cUeB.woff2 kind = high_entropy_blob sizeBytes = 134044 magicHex = [redacted]
High
Ships High Entropy Blob

Package ships high-entropy non-source blobs.

dist/web/assets/bootstrap-icons-mSm7cUeB.woff2View on unpkg

Findings

2 Critical4 High5 Medium7 Low
CriticalRemote Asset Decode Executedist/server/cli.js
CriticalTrigger Reachable Dangerous Capabilitydist/server/cli.js
HighChild Processdist/server/cli.js
HighShell
HighSpawned Bundled Service Listenerdist/server/cli.js
HighShips High Entropy Blobdist/web/assets/bootstrap-icons-mSm7cUeB.woff2
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencedist/server/cli.js
MediumStructural Risk Force Deep Review
MediumWildcard Dependency
LowNon Install Lifecycle Scripts
LowScripts Present
LowWeak Cryptodist/server/cli.js
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings
LowNo License