registry  /  cx-viewer  /  1.0.4

cx-viewer@1.0.4

Codex Logger visualization management tool

AI Security Review

scanned 3h ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. No install-time behavior runs. Explicit cx-viewer commands modify shell/Codex integration and locally proxy Codex API traffic for its viewer/logging feature.

Static reason
One or more suspicious static signals were detected.
Trigger
User runs `cxv -logger` or `cxv run`/CLI mode.
Impact
Can observe and mediate Codex sessions launched through cx-viewer; hooks are inert without its runtime port.
Mechanism
guarded Codex hook/config setup plus loopback API capture proxy
Rationale
Source confirms explicit-user agent integration and session capture, not malicious install-time behavior or an exfiltration chain. Flag as a warning because it modifies user shell/Codex control surfaces and handles sensitive session traffic.
Evidence
package.jsoncli.jslib/ensure-hooks.jsproxy.jsinterceptor.jslib/proxy-env.js~/.zshrc~/.bashrc~/.bash_profile~/.profile~/.codex/hooks.json~/.codex/config.toml~/.codex/auth.json
Network endpoints2
chatgpt.com/backend-api/codexapi.openai.com/v1

Decision evidence

public snapshot
AI called this Suspicious at 89.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for warning
  • `cli.js` explicitly installs shell hooks and edits Codex config during `cxv -logger`/`cxv run`.
  • `lib/ensure-hooks.js` writes `~/.codex/hooks.json` with a broad PermissionRequest matcher.
  • `cli.js` starts a loopback proxy that captures Codex/OpenAI traffic for local logging.
Evidence against
  • `package.json` has only `prepublishOnly`; no install-time lifecycle hook.
  • Hook commands are gated on `CXVIEWER_PORT`, set by cx-viewer runtime.
  • `proxy.js` binds its capture proxy to `127.0.0.1` and forwards to configured OpenAI/ChatGPT endpoints.
  • Reviewed code shows no credential exfiltration, remote payload download, or destructive action.
  • `--uninstall` removes the package's shell hooks and legacy Codex files.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsEvalFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsMinifiedObfuscatedProtestwareTelemetryUrlStrings
ManifestNo manifest risk signals triggered.
scanned 436 file(s), 15.7 MB of source, external domains: 127.0.0.1, api.example.com, api.github.com, api.openai.com, bellard.org, cdn.example.com, chatgpt.com, chevrotain.io, developers.openai.com, en.wikipedia.org, github.com, ipapi.co, ipinfo.io, ipwho.is, lexical.dev, reactjs.org, registry.npmjs.org, stuk.github.io, www.w3.org

Source & flagged code

11 flagged · loading source
findcx.jsView file
4import { homedir, tmpdir } from 'node:os'; L5: import { execSync } from 'node:child_process'; L6: import { threadId } from 'node:worker_threads';
High
Child Process

Package source references child process execution.

findcx.jsView on unpkg · L4
110if (existsSync('/bin/bash')) bypassCmds.push({ cmd: `type -P ${BINARY_NAME}`, shell: '/bin/bash' }); L111: const fallbackCmds = [`which ${BINARY_NAME}`, `command -v ${BINARY_NAME}`].map(c => ({ cmd: c, shell: true })); L112: for (const { cmd, shell } of [...bypassCmds, ...fallbackCmds]) {
High
Shell

Package source references shell execution.

findcx.jsView on unpkg · L110
dist/assets/jszip.min-BxIXdRg4.jsView file
11https://github.[redacted] L12: */var jszip_minExports=(hasRequiredJszip_min||(hasRequiredJszip_min=1,jszip_min$2.exports=function s(a,o,h){function u(r,e2){if(!o[r]){if(!a[r]){if(!e2&&commonjsRequire)return comm...
Low
Eval

Package source references a known benign dynamic code generation pattern.

dist/assets/jszip.min-BxIXdRg4.jsView on unpkg · L11
dist/assets/livescript-Bw1Vw7Ae.jsView file
1var tokenBase=function(stream,state){var next_rule=state.next||"start";state.next=state.next;var nr=Rules[next_rule];if(nr.splice){for(var i$=0;i$<nr.length;++i$){var r=nr[i$];if(r...
Medium
Dynamic Require

Package source references dynamic require/import behavior.

dist/assets/livescript-Bw1Vw7Ae.jsView on unpkg · L1
cli.jsView file
3// 阻止 server.js 自动启动(必须在任何导入之前设置) L4: process.env.CXV_WORKSPACE_MODE = '1'; L5: ... L9: import { homedir } from 'node:os'; L10: import { spawn } from 'node:child_process'; L11: import { t } from './i18n.js'; ... L15: L16: const __dirname = fileURLToPath(new URL('.', import.meta.url)); L17: ... L29: const shell = process.env.SHELL || ''; L30: if (shell.includes('zsh')) return resolve(homedir(), '.zshrc'); L31: if (shell.includes('bash')) {
Medium
Install Persistence

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

cli.jsView on unpkg · L3
server.jsView file
1Manifest entrypoint (manifest.main) carries capability families absent from dist/build output: environment+network, execution+network L1: import { createServer } from 'node:http'; L2: import { createServer as createHttpsServer } from 'node:https'; ... L8: import { homedir, platform, networkInterfaces } from 'node:os'; L9: import { execFile, exec, spawn } from 'node:child_process'; L10: import { promisify } from 'node:util'; ... L20: const child = spawn(cmd, args, { ...options, stdio: ['pipe', 'pipe', 'pipe'] }); L21: let stdout = ''; L22: let stderr = ''; ... L32: } L33: child.stdin.write(input); L34: child.stdin.end(); ... L61: let prefs = {};
High
Entrypoint Build Divergence

Manifest entrypoint contains risky behavior absent from dist/build output.

server.jsView on unpkg · L1
lib/proxy-env.jsView file
1import { EnvHttpProxyAgent, setGlobalDispatcher } from 'undici'; L2: import tls from 'node:tls'; L3: import { execFileSync } from 'node:child_process'; L4: import { existsSync, statSync, writeFileSync, appendFileSync, readFileSync } from 'node:fs'; ... L6: // 纯函数,从 env 中解析代理配置(可独立测试) L7: export function resolveProxyConfig(env = process.env) { L8: const allProxy = env.all_proxy || env.ALL_PROXY;
High
Same File Env Network Execution

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

lib/proxy-env.jsView on unpkg · L1
lib/appserver-bridge.jsView file
2103} L2104: _appServerProcess = spawn(command, appServerArgs, { L2105: cwd, ... L2109: L2110: _appServerProcess.stdout.on('data', (data) => { L2111: if (process.env.CXV_DEBUG) process.stderr.write(`[app-server] ${data}`); L2112: }); ... L2117: // 3. 等待就绪 L2118: await waitForReady(`http://127.0.0.1:${appServerPort}/readyz`); L2119:
High
Command Output Exfiltration

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

lib/appserver-bridge.jsView on unpkg · L2103
build.jsView file
10console.log('🔨 正在执行 Vite 构建...'); L11: execSync('npx vite build', { cwd: __dirname, stdio: 'inherit' }); L12:
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

build.jsView on unpkg · L10
scripts/mac-sign.shView file
path = scripts/mac-sign.sh kind = build_helper sizeBytes = 1173 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

scripts/mac-sign.shView on unpkg
dist/favicon.icoView file
path = dist/favicon.ico kind = high_entropy_blob sizeBytes = 19578 magicHex = [redacted]
High
Ships High Entropy Blob

Package ships high-entropy non-source blobs.

dist/favicon.icoView on unpkg

Findings

7 High7 Medium8 Low
HighChild Processfindcx.js
HighShellfindcx.js
HighEntrypoint Build Divergenceserver.js
HighSame File Env Network Executionlib/proxy-env.js
HighCommand Output Exfiltrationlib/appserver-bridge.js
HighRuntime Package Installbuild.js
HighShips High Entropy Blobdist/favicon.ico
MediumDynamic Requiredist/assets/livescript-Bw1Vw7Ae.js
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencecli.js
MediumProtestware
MediumShips Build Helperscripts/mac-sign.sh
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowEvaldist/assets/jszip.min-BxIXdRg4.js
LowFilesystem
LowObfuscated
LowHigh Entropy Strings
LowTelemetry
LowUrl Strings