registry  /  @agentrhq/webcmd  /  0.2.0

@agentrhq/webcmd@0.2.0

Turn websites, browser sessions, desktop apps, and local tools into deterministic CLI surfaces for humans and AI agents.

AI Security Review

scanned 6d ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. Package has a real agent/CLI extension lifecycle surface in its own ~/.webcmd namespace, but no confirmed malicious install-time hijack. Risk is from lifecycle-maintained user runtime files and user-invoked plugin execution.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
global npm install, CLI startup, or explicit webcmd plugin commands
Impact
Can create or maintain ~/.webcmd runtime files and execute installed webcmd plugins when the user invokes the CLI.
Mechanism
first-party runtime setup plus user-invoked plugin installation/loading
Policy narrative
On global install the package may create shell completion files and package-owned ~/.webcmd state, then runtime startup discovers user adapters/plugins under ~/.webcmd. Plugin installation can clone git sources, install dependencies, symlink or copy plugin code, and import plugin modules later, but this is exposed as an explicit webcmd plugin feature rather than hidden lifecycle execution.
Rationale
The inspected source shows dangerous agent/automation extension capabilities and lifecycle setup inside the package's own namespace, but not unconsented mutation of a foreign AI-agent control surface, credential exfiltration, remote payload execution at install time, or persistence outside the documented product contract. Warn is appropriate for lifecycle extension risk rather than publish block.
Evidence
package.jsonscripts/postinstall.jsscripts/fetch-adapters.jsdist/src/main.jsdist/src/discovery.jsdist/src/plugin.jsdist/src/update-check.js~/.zsh/completions/_webcmd~/.bash_completion.d/webcmd~/.config/fish/completions/webcmd.fish~/.webcmd/spotify.env~/.webcmd/clis~/.webcmd/plugins~/.webcmd/monorepos~/.webcmd/node_modules/@agentrhq/webcmd
Network endpoints2
127.0.0.1:19825/shutdowngithub.com/<user>/<repo>.git

Decision evidence

public snapshot
AI called this Suspicious at 86.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • package.json runs postinstall and preuninstall lifecycle scripts
  • scripts/postinstall.js writes shell completion files and ~/.webcmd/spotify.env on global install
  • scripts/fetch-adapters.js lifecycle-maintains ~/.webcmd/clis and deletes stale package-owned overrides
  • dist/src/main.js startup creates ~/.webcmd runtime shims and loads user adapters/plugins
  • dist/src/plugin.js user-invoked plugin install can git clone, npm install, symlink, transpile, and later import plugins
Evidence against
  • No lifecycle write to CLAUDE.md, .mcp.json, Codex/Cursor/Claude config, or other foreign AI-agent control surface found
  • postinstall is guarded to CI skip and global npm install for completions/adapter sync
  • Network in preuninstall targets localhost shutdown only
  • Update check network is disabled by UPDATE_CHECKS_ENABLED=false
  • Remote plugin cloning is CLI user-invoked, not install-time
  • No credential harvesting or exfiltration logic found in inspected lifecycle/entry files
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsEvalFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsTelemetryUrlStrings
ManifestNo manifest risk signals triggered.
scanned 1,252 file(s), 6.91 MB of source, external domains: 127.0.0.1, a.com, a.example, a9.com, aave.com, accounts.google.com, accounts.pixiv.net, accounts.spotify.com, ads.example, api.chess.com, api.coingecko.com, api.dictionaryapi.dev, api.example, api.example.com, api.fda.gov, api.github.com, api.grok.com, api.llama.fi, api.manus.im, api.npmjs.org, api.nuget.org, api.openalex.org, api.osv.dev, api.semanticscholar.org, api.slock.ai, api.spotify.com, api.stackexchange.com, api.test, api.tvmaze.com, api2.openreview.net, app.example, app.mercury.com, app.slock.ai, archive.org, arxiv.org, assets.bwbx.io, assets.grok.com, auth.band.us, auth.openai.com, azuresearch-usnc.nuget.org, b.example, bitcoin.org, browser.example.com, ca.linkedin.com, cdn.example.com, cdn.example.invalid, cdn.openai.com, cdn.site.com, cdn.slock.ai, cdn1.suno.ai

Source & flagged code

11 flagged · loading source
package.jsonView file
scripts.postinstall = node scripts/postinstall.js || true; node scripts/fetch-adapters.js || true
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
scripts.postinstall = node scripts/postinstall.js || true; node scripts/fetch-adapters.js || true
Medium
Ambiguous Install Lifecycle Script

Install-time lifecycle script is not statically allowlisted and needs review.

package.jsonView on unpkg
dist/src/external.jsView file
4import { fileURLToPath } from 'node:url'; L5: import { spawnSync, execFileSync } from 'node:child_process'; L6: import yaml from 'js-yaml';
High
Child Process

Package source references child process execution.

dist/src/external.jsView on unpkg · L4
dist/src/plugin.jsView file
491stdio: ['pipe', 'pipe', 'pipe'], L492: ...(isWindows && { shell: true }), L493: });
High
Shell

Package source references shell execution.

dist/src/plugin.jsView on unpkg · L491
dist/src/browser.test.jsView file
294// Should not throw when parsed L295: expect(() => new Function(js)).not.toThrow(); L296: });
Low
Eval

Package source references a known benign dynamic code generation pattern.

dist/src/browser.test.jsView on unpkg · L294
dist/src/discovery.jsView file
256return; L257: await import(pathToFileURL(filePath).href).catch((err) => { L258: log.warn(`Failed to load module ${filePath}: ${getErrorMessage(err)}`);
Medium
Dynamic Require

Package source references dynamic require/import behavior.

dist/src/discovery.jsView on unpkg · L256
clis/grok/image.jsView file
6L7: const GROK_URL = 'https://grok.com/'; L8: const SESSION_HINT = 'Likely login/auth/challenge/session issue in the existing grok.com browser session.'; ... L204: // refuse direct curl/node downloads. L205: async function fetchImageAsBase64(page, url) { L206: const urlJson = JSON.stringify(url);
Low
Weak Crypto

Package source references weak cryptographic algorithms.

clis/grok/image.jsView on unpkg · L6
scripts/postinstall.jsView file
7* standard completion directory. For zsh and bash, the script prints manual L8: * instructions instead of modifying rc files (~/.zshrc, ~/.bashrc) — this L9: * avoids breaking multi-line shell commands and other fragile rc structures. ... L60: function detectShell() { L61: const shell = process.env.SHELL || ''; L62: if (shell.includes('zsh')) return 'zsh'; ... L77: // Skip in CI environments L78: if (process.env.CI || process.env.CONTINUOUS_INTEGRATION) { L79: return; ... L93: L94: const home = homedir(); L95:
Medium
Install Persistence

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

scripts/postinstall.jsView on unpkg · L7
dist/src/cli.jsView file
100Cross-file remote execution chain: dist/src/cli.js spawns dist/src/browser/network-interceptor.js; helper contains network access plus dynamic code execution. L100: try { L101: body = JSON.parse(preview); L102: } ... L130: catch { L131: if (process.env.WEBCMD_VERBOSE) L132: log.warn(`[network] Failed to parse interceptor buffer: ${typeof raw === 'string' ? raw.slice(0, 200) : String(raw)}`); ... L144: } L145: /** Exit codes by network error code — usage errors vs runtime failures. */ L146: const NETWORK_ERROR_EXIT = { ... L148: invalid_filter: EXIT_CODES.USAGE_ERROR, L149: invalid_max_body: EXIT_CODES.USAGE_ERROR, L150: };
High
Cross File Remote Execution Context

Source spawns a local helper that also contains network and dynamic execution context; review data flow before blocking.

dist/src/cli.jsView on unpkg · L100
dist/src/download/index.jsView file
matchType = previous_version_dangerous_delta matchedPackage = @agentrhq/webcmd@0.1.2 matchedIdentity = npm:QGFnZW50cmhxL3dlYmNtZA:0.1.2 similarity = 0.783 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/src/download/index.jsView on unpkg
dist/src/observation/redaction.test.jsView file
28patternName = generic_password severity = medium line = 28 matchedText = password...D]',
Medium
Secret Pattern

Hardcoded password in dist/src/observation/redaction.test.js

dist/src/observation/redaction.test.jsView on unpkg · L28

Findings

1 Critical4 High7 Medium8 Low
CriticalPrevious Version Dangerous Deltadist/src/download/index.js
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processdist/src/external.js
HighShelldist/src/plugin.js
HighCross File Remote Execution Contextdist/src/cli.js
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumDynamic Requiredist/src/discovery.js
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencescripts/postinstall.js
MediumStructural Risk Force Deep Review
MediumSecret Patterndist/src/observation/redaction.test.js
LowNon Install Lifecycle Scripts
LowScripts Present
LowEvaldist/src/browser.test.js
LowWeak Cryptoclis/grok/image.js
LowFilesystem
LowHigh Entropy Strings
LowTelemetry
LowUrl Strings