registry  /  @agentrhq/webcmd  /  0.2.2

@agentrhq/webcmd@0.2.2

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

AI Security Review

scanned 2h ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. No confirmed malicious attack chain was established. The package does perform first-party install/runtime setup under ~/.webcmd and shell completion directories, plus explicit plugin/browser capabilities aligned with its CLI purpose.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
Global npm install, uninstall, or explicit webcmd CLI commands
Impact
May mutate package-owned local configuration/overrides; no evidence of stealth persistence, credential exfiltration, or remote payload execution during install.
Mechanism
first-party lifecycle setup and user-invoked extension/plugin runtime
Rationale
Static source inspection shows broad dual-use browser/plugin automation and lifecycle setup, but the dangerous primitives are package-aligned or user-invoked and no concrete malicious chain is present. Because install hooks mutate first-party Webcmd state, warn rather than block.
Evidence
package.jsonscripts/postinstall.jsscripts/fetch-adapters.jsdist/src/main.jsdist/src/discovery.jsdist/src/external.jsdist/src/skills.jsdist/src/plugin.jsdist/src/update-check.jsdist/src/daemon/server.js~/.zsh/completions/_webcmd~/.bash_completion.d/webcmd~/.config/fish/completions/webcmd.fish~/.webcmd/spotify.env~/.webcmd/clis~/.webcmd/adapter-manifest.json~/.webcmd/node_modules/@agentrhq/webcmd~/.webcmd/plugins
Network endpoints3
127.0.0.1:9777/shutdowninvalid.example/webcmd/latestinvalid.example/webcmd/releases

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 completions and ~/.webcmd/spotify.env on global install
  • scripts/fetch-adapters.js can delete stale ~/.webcmd/clis site override directories and legacy shim files
  • dist/src/discovery.js creates ~/.webcmd/node_modules/@agentrhq/webcmd symlink/runtime files at CLI startup
  • dist/src/plugin.js supports explicit user plugin installs from git/local sources with dependency install
Evidence against
  • scripts/postinstall.js is gated to global installs and only prints rc-file instructions instead of editing shell rc files
  • scripts/fetch-adapters.js states no network calls and hashes packaged clis before sparse cleanup
  • dist/src/update-check.js has UPDATE_CHECKS_ENABLED=false and uses invalid.example placeholders
  • dist/src/external.js parses install commands and rejects shell operators before execFileSync
  • plugin install, skill install, browser/daemon actions are explicit CLI commands, not import-time payloads
  • No credential harvesting or external exfiltration found in inspected lifecycle/main paths
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsEvalFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsTelemetryUrlStrings
ManifestNo manifest risk signals triggered.
scanned 1,262 file(s), 7.02 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.test.jsView file
9})); L10: vi.mock('node:child_process', () => ({ L11: spawnSync: vi.fn(),
High
Child Process

Package source references child process execution.

dist/src/external.test.jsView on unpkg · L9
115expect(spawnMock).toHaveBeenNthCalledWith(1, 'tg', ['send', 'hello world', '--to', 'a"b'], { stdio: 'inherit' }); L116: expect(spawnMock).toHaveBeenNthCalledWith(2, 'tg send "hello world" --to "a""b"', { stdio: 'inherit', shell: true }); L117: expect(process.exitCode).toBe(0);
High
Shell

Package source references shell execution.

dist/src/external.test.jsView on unpkg · L115
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
257return; L258: await import(pathToFileURL(filePath).href).catch((err) => { L259: 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 · L257
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
matchType = previous_version_dangerous_delta matchedPackage = @agentrhq/webcmd@0.2.0 matchedIdentity = npm:QGFnZW50cmhxL3dlYmNtZA:0.2.0 similarity = 0.883 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/cli.jsView on unpkg
62Cross-file remote execution chain: dist/src/cli.js spawns dist/src/browser/network-interceptor.js; helper contains network access plus dynamic code execution. L62: function isInteractiveInstall(opts) { L63: return !opts.json && process.stdin.isTTY === true && process.stdout.isTTY === true; L64: } ... L165: try { L166: body = JSON.parse(preview); L167: } ... L195: catch { L196: if (process.env.WEBCMD_VERBOSE) L197: log.warn(`[network] Failed to parse interceptor buffer: ${typeof raw === 'string' ? raw.slice(0, 200) : String(raw)}`); ... L213: invalid_filter: EXIT_CODES.USAGE_ERROR, L214: invalid_max_body: EXIT_CODES.USAGE_ERROR, L215: };
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 · L62
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/cli.js
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processdist/src/external.test.js
HighShelldist/src/external.test.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