registry  /  @0xmaxma/claude-gateway  /  1.3.23

@0xmaxma/claude-gateway@1.3.23

Multi-agent gateway for Claude

AI Security Review

scanned 2h ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. Starting the gateway copies package and user shared skill definitions into `~/.claude/skills/`. Authenticated runtime features can invoke the local Claude CLI and fetch an app registry for explicit app management.

Static reason
High-risk behavior combination matched malicious policy.; previous stored version diff introduced dangerous source
Trigger
User starts `claude-gateway`; authenticated API/wizard or app-management requests activate additional capabilities.
Impact
The package can alter a Claude skills directory and expose high-privilege local AI automation if deployed with its API credentials.
Mechanism
Claude skill synchronization plus authenticated local subprocess and app-management operations.
Rationale
The package is not proven malicious, but startup mutation of a Claude skills directory and privileged AI/app-management capability warrant a warning. The postinstall is package-owned dependency setup rather than an unconsented foreign agent-control mutation.
Evidence
package.jsondist/index.jsdist/skills/sync.jsdist/api/router.jsdist/api/auth.jsdist/apps/registry-client.jsdist/apps/installer.js~/.claude/skills/~/.claude-gateway/shared-skills/~/.claude-gateway/.envmcp/
Network endpoints3
raw.githubusercontent.com/0xMaxMa/claude-gateway-appstore/main/apps.jsonapi.telegram.orgdiscord.com/api/v10

Decision evidence

public snapshot
AI called this Suspicious at 87.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • `dist/index.js` syncs bundled/shared skills into `~/.claude/skills/` on gateway startup.
  • `dist/skills/sync.js` creates, overwrites, and removes marker-owned skill files under that Claude control surface.
  • `dist/api/router.js` runs `claude --print --dangerously-skip-permissions` for wizard requests.
  • `dist/apps/registry-client.js` fetches an app registry from GitHub; installer code can run container tooling.
  • `package.json` postinstall runs `bun install --cwd mcp` when Bun is present.
Evidence against
  • Postinstall only installs the package's own `mcp` dependencies; it does not modify Claude configuration.
  • No source-backed secret harvesting followed by transmission was found.
  • Observed Telegram/Discord requests implement configured bot verification and messaging.
  • API mutations and the wizard subprocess route are authenticated in `dist/api/router.js`.
  • No eval, encoded payload, stealth persistence, or arbitrary remote code-loading chain was confirmed.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsUrlStrings
Manifest
NoLicense
scanned 104 file(s), 1.21 MB of source, external domains: 127.0.0.1, api.telegram.org, cdn.jsdelivr.net, discord.com, github.com, raw.githubusercontent.com, registry.npmjs.org

Source & flagged code

8 flagged · loading source
package.jsonView file
scripts.postinstall = if command -v bun >/dev/null 2>&1; then bun install --cwd mcp; else echo 'Warning: bun not found. Run `cd mcp && bun install` manually to enable MCP tools.'; fi
Critical
Red Install Lifecycle Script

Install-time lifecycle script matches a deterministic static-gate block pattern.

package.jsonView on unpkg
scripts.postinstall = if command -v bun >/dev/null 2>&1; then bun install --cwd mcp; else echo 'Warning: bun not found. Run `cd mcp && bun install` manually to enable MCP tools.'; fi
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
dist/discord/receiver.jsView file
36exports.DiscordReceiver = void 0; L37: const child_process_1 = require("child_process"); L38: const path = __importStar(require("path"));
High
Child Process

Package source references child process execution.

dist/discord/receiver.jsView on unpkg · L36
dist/api/router.jsView file
42const path = __importStar(require("path")); L43: const child_process_1 = require("child_process"); L44: const runner_1 = require("../agent/runner"); ... L81: }; L82: const TELEGRAM_API_BASE = process.env.TELEGRAM_API_BASE ?? 'https://api.telegram.org'; L83: /** Max simultaneous wizard/start Claude subprocesses to prevent resource exhaustion. */ ... L85: const WIZARD_MAX_CONCURRENT = 2; L86: /** Call Claude --print with stdin prompt; resolves with stdout on exit 0. */ L87: function runClaude(prompt, timeoutMs = 120000) { ... L100: if (code === 0) L101: resolve(Buffer.concat(out).toString('utf-8')); L102: else
Critical
Command Output Exfiltration

Source executes local commands and sends command output to an external endpoint.

dist/api/router.jsView on unpkg · L42
42Trigger-reachable chain: manifest.main -> dist/index.js -> dist/api/gateway-router.js -> dist/api/router.js L42: const path = __importStar(require("path")); L43: const child_process_1 = require("child_process"); L44: const runner_1 = require("../agent/runner"); ... L81: }; L82: const TELEGRAM_API_BASE = process.env.TELEGRAM_API_BASE ?? 'https://api.telegram.org'; L83: /** Max simultaneous wizard/start Claude subprocesses to prevent resource exhaustion. */ ... L85: const WIZARD_MAX_CONCURRENT = 2; L86: /** Call Claude --print with stdin prompt; resolves with stdout on exit 0. */ L87: function runClaude(prompt, timeoutMs = 120000) { ... L100: if (code === 0) L101: resolve(Buffer.concat(out).toString('utf-8')); L102: else
Critical
Trigger Reachable Dangerous Capability

A package entrypoint or install-time lifecycle script reaches a source file with blocking dangerous behavior.

dist/api/router.jsView on unpkg · L42
matchType = previous_version_dangerous_delta matchedPackage = @0xmaxma/claude-gateway@1.3.20 matchedIdentity = npm:QDB4bWF4bWEvY2xhdWRlLWdhdGV3YXk:1.3.20 similarity = 0.931 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/api/router.jsView on unpkg
81}; L82: const TELEGRAM_API_BASE = process.env.TELEGRAM_API_BASE ?? 'https://api.telegram.org'; L83: /** Max simultaneous wizard/start Claude subprocesses to prevent resource exhaustion. */ ... L88: return new Promise((resolve, reject) => { L89: const child = (0, child_process_1.spawn)('claude', ['--print', '--dangerously-sk[redacted]'], { L90: env: { ...process.env },
High
Same File Env Network Execution

A single source file combines environment access, network access, and code or shell execution; review context before blocking.

dist/api/router.jsView on unpkg · L81
dist/api/packages.jsView file
192try { L193: (0, child_process_1.execSync)(`npm install -g ${packageName}@latest`, { L194: stdio: ['pipe', 'pipe', 'pipe'],
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

dist/api/packages.jsView on unpkg · L192

Findings

4 Critical5 High3 Medium5 Low
CriticalRed Install Lifecycle Scriptpackage.json
CriticalCommand Output Exfiltrationdist/api/router.js
CriticalTrigger Reachable Dangerous Capabilitydist/api/router.js
CriticalPrevious Version Dangerous Deltadist/api/router.js
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processdist/discord/receiver.js
HighShell
HighSame File Env Network Executiondist/api/router.js
HighRuntime Package Installdist/api/packages.js
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings
LowNo License