registry  /  claude-codex-wechat  /  0.1.33

claude-codex-wechat@0.1.33

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

AI Security Review

scanned 5h ago · by lpm-firewall-ai

Install-time lifecycle code silently mutates the user's Codex MCP configuration by adding a package-supplied MCP server. That server gives Codex tools for sending arbitrary local file paths through the WeChat bridge and running a downloader helper.

Static reason
High-risk behavior combination matched malicious policy.; source matched previously finalized malicious package; routed for review; previous stored version diff introduced dangerous source
Trigger
npm install runs the postinstall lifecycle when `codex` is present
Impact
Foreign AI-agent control surface is modified at install time, granting the package persistent agent tools capable of file transmission via the local bridge.
Mechanism
unconsented global Codex MCP registration
Attack narrative
On npm install, the postinstall script checks for Codex and then runs `codex mcp add wechat-media ... node dist/mcp/mediaServer.js`, silently registering a package MCP server into Codex. The registered server exposes agent-callable tools to send arbitrary local file paths to the package's WeChat bridge and to execute a downloader helper from package or user skill locations. This is an unconsented lifecycle mutation of a broad AI-agent control surface.
Rationale
The package crosses the block boundary because a lifecycle hook silently registers a package-controlled MCP server into Codex, a foreign/broad AI-agent control surface. The planted tools are product-themed, but the install-time unconsented delivery is the blockable behavior under policy.
Evidence
package.jsonscripts/postinstall-codex-mcp.mjsdist/mcp/mediaServer.jsdist/server/cli.js~/.agents/skills/douyin-download/scripts/douyin-download.mjs~/.claude/skills/douyin-download/scripts/douyin-download.mjs
Network endpoints3
localhost:8787ilinkai.weixin.qq.comwss://wechat.style520.com/agent

Decision evidence

public snapshot
AI called this Malicious at 96.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for block
  • package.json postinstall runs scripts/postinstall-codex-mcp.mjs on install
  • postinstall executes `codex mcp remove/add wechat-media` without user confirmation
  • postinstall registers dist/mcp/mediaServer.js into Codex with BRIDGE_API_URL=http://localhost:8787
  • dist/mcp/mediaServer.js exposes MCP tools that send arbitrary file paths to the WeChat bridge
  • dist/mcp/mediaServer.js can exec a douyin-download script from package/user skill locations
Evidence against
  • No install-time network fetch or decoded remote code execution found in inspected postinstall source
  • MCP endpoints are mostly localhost/package-aligned for a WeChat bridge
  • Main CLI service and persistence are user-invoked commands, not import-time execution
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsMinifiedUrlStrings
Manifest
NoLicenseWildcardDependency
scanned 4 file(s), 474 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

12 flagged · loading source
package.jsonView file
scripts.postinstall = node scripts/postinstall-codex-mcp.mjs
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
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
matchType = normalized_sha256 matchedPackage = claude-codex-wechat@0.1.31 matchedPath = dist/server/cli.js matchedIdentity = npm:Y2xhdWRlLWNvZGV4LXdlY2hhdA:0.1.31 similarity = 1.000 summary = normalized source hash matched finalized malicious source
High
Known Malware Source Similarity

Source file is highly similar to a previously finalized malicious package; route for source-aware review.

dist/server/cli.jsView on unpkg
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/mcp/mediaServer.jsView file
matchType = previous_version_dangerous_delta matchedPackage = claude-codex-wechat@0.1.30 matchedIdentity = npm:Y2xhdWRlLWNvZGV4LXdlY2hhdA:0.1.30 similarity = 0.667 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/mcp/mediaServer.jsView on unpkg
94// src/mcp/tools/douyinDownload.ts L95: import { execFile } from "node:child_process"; L96: import { existsSync } from "node:fs"; ... L100: import { z as z2 } from "zod"; L101: var BRIDGE_API_URL2 = process.env.BRIDGE_API_URL || "http://localhost:8787"; L102: function findDouyinScript() {
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/mediaServer.jsView on unpkg · L94
121return new Promise((resolve2, reject) => { L122: execFile("node", [script, ...args], { timeout: 12e4 }, (err, stdout, stderr) => { L123: if (err) reject(new Error(stderr || err.message)); ... L129: const fileName = basename2(filePath) || "video.mp4"; L130: const response = await fetch(`${BRIDGE_API_URL2}/api/channel/send-media`, { L131: method: "POST", L132: headers: { "content-type": "application/json" }, L133: body: JSON.stringify({ kind, filePath, fileName }) L134: });
High
Command Output Exfiltration

Source combines command execution, command-output handling, and outbound requests; review data flow before blocking.

dist/mcp/mediaServer.jsView on unpkg · L121
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

3 Critical8 High5 Medium7 Low
CriticalRemote Asset Decode Executedist/server/cli.js
CriticalTrigger Reachable Dangerous Capabilitydist/server/cli.js
CriticalPrevious Version Dangerous Deltadist/mcp/mediaServer.js
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processdist/server/cli.js
HighShell
HighSame File Env Network Executiondist/mcp/mediaServer.js
HighCommand Output Exfiltrationdist/mcp/mediaServer.js
HighSpawned Bundled Service Listenerdist/server/cli.js
HighShips High Entropy Blobdist/web/assets/bootstrap-icons-mSm7cUeB.woff2
HighKnown Malware Source Similaritydist/server/cli.js
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