registry  /  @plumpslabs/fennec-core  /  1.13.1

@plumpslabs/fennec-core@1.13.1

Fennec MCP server — AI-native browser, terminal, and process observability

AI Security Review

scanned 3h ago · by lpm-firewall-ai

The explicit mobile MCP tools accept a caller-provided Android device identifier. That value is interpolated into shell strings passed to `execSync`, permitting command injection when an MCP client invokes affected tools.

Static reason
One or more suspicious static signals were detected.
Trigger
Start `FennecServer` and invoke a mobile MCP tool with a crafted `deviceId`.
Impact
An MCP client able to call the server can execute arbitrary commands with the server process's privileges.
Mechanism
Shell command injection through unquoted ADB device identifier interpolation.
Rationale
Source inspection shows a concrete caller-triggered command-injection vulnerability, not an intentional malicious payload. Flag it as a dangerous capability/critical vulnerability requiring a warning rather than a publication block.
Evidence
package.jsonREADME.mddist/index.jsdist/cdp-engine-TGY7DD37.js

Decision evidence

public snapshot
AI called this Suspicious at 97.0% confidence as Critical Vulnerability with low false-positive risk.
Evidence for warning
  • `dist/index.js` passes caller-controlled `deviceId` into shell command strings used by `execSync`.
  • Mobile MCP handlers accept unrestricted string `deviceId` values and invoke the ADB helper.
  • `dist/index.js` exposes caller-invoked process spawning and browser JavaScript evaluation.
Evidence against
  • `package.json` has no `preinstall`, `install`, `postinstall`, or `uninstall` hook.
  • No import-time remote fetch, credential harvesting, exfiltration, or foreign AI-agent config mutation was found.
  • Observed network endpoints are local CDP/WebView URLs; no package-controlled remote endpoint exists.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 5 file(s), 543 KB of source, external domains: 127.0.0.1

Source & flagged code

2 flagged · loading source
dist/index.jsView file
4340// src/process/PortDetector.ts L4341: import { execSync } from "child_process"; L4342: var PortDetector = class {
High
Child Process

Package source references child process execution.

dist/index.jsView on unpkg · L4340
14Cross-file remote execution chain: dist/index.js spawns dist/cdp-engine-TGY7DD37.js; helper contains network access plus dynamic code execution. L14: import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js"; L15: import { createServer } from "http"; L16: import { ZodError } from "zod"; ... L754: return { L755: base64: buffer.toString("base64"), L756: width: clip?.width ?? viewport.width, ... L1154: category: "dom", L1155: description: "`<use_case>SEO/Meta inspection</use_case> Get page metadata: title, description, Open Graph tags, Twitter cards, canonical URL, favicon, and viewport info. title, des... L1156: inputSchema: z3.object({ ... L1925: code: "STORAGE_ACCESS_DENIED", L1926: suggestions: ["localStorage may be restricted in private browsing or cross-origin contexts"] L1927: });
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/index.jsView on unpkg · L14

Findings

3 High2 Medium4 Low
HighChild Processdist/index.js
HighShell
HighCross File Remote Execution Contextdist/index.js
MediumNetwork
MediumEnvironment Vars
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings