registry  /  langcli-com  /  0.1.42

langcli-com@0.1.42

Langcli - interactive AI coding assistant in the terminal

AI Security Review

scanned 3h ago · by lpm-firewall-ai

LPM blocks this version under the AI-agent control-surface policy. Install-time code automatically registers a Chrome MCP bridge. This mutates an AI-agent/browser control surface outside the package directory without an explicit user action.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
npm installation executes the `postinstall` lifecycle hook.
Impact
A dependency-provided MCP bridge is registered for Chrome and user-profile state is created, potentially expanding an AI agent's browser-control capability.
Mechanism
postinstall execution of a package-supplied Chrome MCP bridge registration command.
Policy narrative
During installation, `postinstall` launches the `@claude-code-best/mcp-chrome-bridge` CLI. With no user-supplied arguments it creates a per-user log directory, runs `fix-permissions`, then runs `register --browser chrome`, followed by `doctor`. The automatic registration targets a Chrome MCP integration rather than package-local setup and is only bypassed through `CLAUDE_CODE_SKIP_CHROME_MCP_SETUP=1`.
Rationale
The package performs unconsented install-time registration of a Chrome MCP bridge, a foreign/broad AI-agent control surface. No direct exfiltration was confirmed, but the lifecycle mutation meets the firewall block boundary.
Evidence
package.jsonscripts/setup-chrome-mcp.mjs@claude-code-best/mcp-chrome-bridge/dist/cli.js~/Library/Logs/mcp-chrome-bridge%LOCALAPPDATA%/mcp-chrome-bridge/logs~/.local/state/mcp-chrome-bridge/logs

Decision evidence

public snapshot
AI called this Malicious at 94.0% confidence as Malware with low false-positive risk.
Evidence for policy block
  • `package.json` runs `node scripts/setup-chrome-mcp.mjs` as `postinstall`.
  • `scripts/setup-chrome-mcp.mjs` automatically invokes the bridge CLI with `register --browser chrome`.
  • The setup runs without an explicit user command and only offers an opt-out environment variable.
  • The lifecycle script creates Chrome MCP bridge state/log directories in the user profile.
Evidence against
  • The setup script contains no direct network request or credential-harvesting code.
  • It uses `execFileSync` with fixed `node` arguments rather than a shell string.
  • `prepare` only sets a repository-local Git hooks path.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemShell
Supply chain
HighEntropyStringsUrlStrings
Manifest
NoLicense
scanned 1 file(s), 258 KB of source, external domains: 127.0.0.1
Oversized source lightweight scan
dist/cli.js26.5 MB file, sampled 256 KB
FilesystemChildProcessEnvironmentVarsCryptoShellHighEntropyStringsUrlStrings127.0.0.1

Source & flagged code

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

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
scripts/setup-chrome-mcp.mjsView file
10Install-time AI-agent control hijack evidence: L11: import { execFileSync } from 'node:child_process' L12: import { mkdirSync } from 'node:fs' L13: import { createRequire } from 'node:module' ... L16: L17: if (process.env.CLAUDE_CODE_SKIP_CHROME_MCP_SETUP === '1') { L18: process.exit(0) ... L57: L58: mkdirSync(getChromeMcpLogDir(), { recursive: true }) L59: Payload evidence from scripts/setup-chrome-mcp.mjs: L10: L11: import { execFileSync } from 'node:child_process' L12: import { mkdirSync } from 'node:fs' ... L16: L17: if (process.env.CLAUDE_CODE_SKIP_CHROME_MCP_SETUP === '1') { L18: process.exit(0) ... L28: function getChromeMcpLogDir() { L29: const home = homedir() L30: if (process.platform === 'darwin') { L31: return join(home, 'Library', 'Logs', 'mcp-chrome-bridge')
Critical
Ai Agent Control Hijack

Install-time source drops package-supplied AI-agent/MCP control files or instructions.

scripts/setup-chrome-mcp.mjsView on unpkg · L10
dist/vendor/audio-capture/x64-darwin/audio-capture.nodeView file
path = dist/vendor/audio-capture/x64-darwin/audio-capture.node kind = native_binary sizeBytes = 439076 magicHex = [redacted]
Medium
Ships Native Binary

Package ships native binary artifacts.

dist/vendor/audio-capture/x64-darwin/audio-capture.nodeView on unpkg
dist/cli.jsView file
path = dist/cli.js kind = oversized_source_file sizeBytes = 27790665 magicHex = [redacted]
High
Oversized Source File

Package contains source files above the static scanner size ceiling.

dist/cli.jsView on unpkg
path = dist/cli.js kind = oversized_cli_entrypoint sizeBytes = 27790665 magicHex = [redacted]
Medium
Oversized Cli Entrypoint

Package contains an oversized executable-looking CLI entrypoint.

dist/cli.jsView on unpkg

Findings

1 Critical2 High4 Medium6 Low
CriticalAi Agent Control Hijackscripts/setup-chrome-mcp.mjs
HighInstall Time Lifecycle Scriptspackage.json
HighOversized Source Filedist/cli.js
MediumEnvironment Vars
MediumShips Native Binarydist/vendor/audio-capture/x64-darwin/audio-capture.node
MediumOversized Cli Entrypointdist/cli.js
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings
LowNo License