registry  /  cc-viewer  /  1.6.331

cc-viewer@1.6.331

Claude Code logging, visualization, and management toolkit — launch a web viewer alongside Claude Code with full request/response tracing, proxy, and mobile support

AI Security Review

scanned 11d ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. No install-time or import-time malware was confirmed. The package is an agent-facing Claude Code viewer/proxy whose CLI can intentionally install hooks and shell integration when invoked.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
User runs ccv, ccv -logger, ccv --im, or related CLI modes.
Impact
Can intercept/log Claude Code traffic locally and alter Claude hook/shell config as a documented integration; no confirmed unconsented lifecycle mutation or exfiltration.
Mechanism
user-invoked Claude Code proxy, hook registration, and shell wrapper integration
Rationale
Static inspection found dangerous agent-extension behavior only in documented, user-invoked CLI paths, not npm lifecycle or import-time execution. Because it registers Claude hooks and supports permission-bypass modes, this is warn-worthy agent extension lifecycle risk rather than confirmed malware.
Evidence
package.jsoncli.jsserver/lib/ensure-hooks.jsserver/routes/skills.jsfindcc.jsREADME.md~/.claude/settings.json~/.zshrc~/.bashrc~/.bash_profile~/.profile~/.claude/cc-viewer/profile.json
Network endpoints3
127.0.0.1localhost:7008api.example.com

Decision evidence

public snapshot
AI called this Suspicious at 86.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • CLI runtime can write Claude Code hooks into ~/.claude/settings.json via ensureHooks().
  • ccv -logger can modify shell rc files and inject Claude CLI wrapper code; user-invoked integration.
Evidence against
  • package.json has no install/postinstall/prepare hook; prepublishOnly is publisher-side build only.
  • server/routes/skills.js scanner Unicode concern maps to zero-width stripping, not hidden control flow.
  • Hook commands are guarded on CCVIEWER_PORT and marked cc-viewer-managed; uninstall removes managed hooks.
  • Network behavior observed is loopback proxy/viewer plus user-configurable API base URLs, aligned with package purpose.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsEvalFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsMinifiedObfuscatedProtestwareTelemetryUrlStrings
ManifestNo manifest risk signals triggered.
scanned 286 file(s), 12.7 MB of source, external domains: 127.0.0.1, api.anthropic.com, api.dingtalk.com, bellard.org, cdn.discordapp.com, cdn.example.com, chevrotain.io, claude.ai, discord.com, en.wikipedia.org, fb.me, github.com, ipapi.co, ipinfo.io, ipwho.is, lexical.dev, open.feishu.cn, open.larksuite.com, radix-ui.com, reactjs.org, registry.npmjs.org, stuk.github.io, www.w3.org

Source & flagged code

8 flagged · loading source
dist/assets/jszip.min-PwTGeWmJ.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-PwTGeWmJ.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
server/lib/claude-md-discovery.jsView file
7* - 项目候选:从 cwd 实际路径(realpath 后)向上走,每层若 <dir>/CLAUDE.md 存在且为文件,收一条。 L8: * 终止条件:dir === dirname(dir)(fs root) / dir === homedir() / <dir>/.git 存在 / depth 达 8(任一即停)。 L9: * 三种终止条件(homedir / .git / fs root)都先收当前层再停——pushIfFile 在终止判定之前无条件执行。 ... L75: // ── 项目链遍历 ───────────────────────────────────────────────────────────── L76: if (process.platform !== 'win32') { L77: const startReal = safeRealpath(cwd) || cwd; ... L170: tail: entry.tail, L171: content: buf.toString('utf-8'), L172: real,
Low
Weak Crypto

Package source references weak cryptographic algorithms.

server/lib/claude-md-discovery.jsView on unpkg · L7
server/lib/terminal-env.jsView file
7L8: function shouldKeepClaudeNoFlicker(env = {}, sourceEnv = process.env) { L9: return env[KEEP_CLAUDE_NO_FLICKER_ENV] === '1' || sourceEnv?.[KEEP_CLAUDE_NO_FLICKER_ENV] === '1'; ... L53: * Claude spawns, but not for scratch/fallback shells: users often export the L54: * variable from ~/.zshrc or ~/.bashrc, so the shell would recreate it before L55: * they type `claude`. For those shells we install a tiny rc wrapper that loads ... L64: const shellBase = basename(shell); L65: const homeDir = options.homeDir || homedir(); L66: const rcDir = options.rcDir || defaultRcDir();
Medium
Install Persistence

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

server/lib/terminal-env.jsView on unpkg · L7
server/interceptor.jsView file
12Manifest entrypoint (manifest.exports) carries capability families absent from dist/build output: environment+network, execution+network, builtin-tampering L12: import { renameSyncWithRetry } from './lib/file-api.js'; L13: import http from 'node:http'; L14: import https from 'node:https'; ... L23: const __filename = fileURLToPath(import.meta.url); L24: const __dirname = dirname(__filename); L25: L26: // Live-streaming 用的端口:由 server.js 在 listen 成功后通过 setLivePort 注入。 L27: // 不用 process.env.CCVIEWER_PORT 是为了避免主进程 env 污染被 child_process.spawn L28: // 继承到 Bash 工具子进程 / MCP server / Electron tab-worker 等无关进程。 ... L96: if (existsSync(p)) { L97: const data = JSON.parse(readFileSync(p, 'utf-8')); L98: return typeof data?.activeId === 'string' ? data.activeId : null;
High
Entrypoint Build Divergence

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

server/interceptor.jsView on unpkg · L12
server/routes/skills.jsView file
112contains invisible/control Unicode U+200B (zero width space) .replace(/[<U+200B>-<U+200F><U+202A>-<U+202E><U+2060><U+FEFF>]/g, '');
Critical
Trojan Source Unicode

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

server/routes/skills.jsView on unpkg · L112
Trigger-reachable chain: manifest.main -> server.js -> server/server.js -> server/routes/skills.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.

server/routes/skills.jsView 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

2 Critical2 High6 Medium9 Low
CriticalTrojan Source Unicodeserver/routes/skills.js
CriticalTrigger Reachable Dangerous Capabilityserver/routes/skills.js
HighEntrypoint Build Divergenceserver/interceptor.js
HighShips High Entropy Blobdist/favicon.ico
MediumDynamic Requiredist/assets/livescript-Bw1Vw7Ae.js
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistenceserver/lib/terminal-env.js
MediumProtestware
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowEvaldist/assets/jszip.min-PwTGeWmJ.js
LowWeak Cryptoserver/lib/claude-md-discovery.js
LowFilesystem
LowObfuscated
LowHigh Entropy Strings
LowTelemetry
LowUrl Strings