registry  /  zevairouter  /  1.0.28

zevairouter@1.0.28

ZevaiRouter - AI Router with provider automation, multi-account workflows, and quota tracking

AI Security Review

scanned 6d ago · by lpm-firewall-ai

No confirmed malicious attack surface was established. The package has high-risk router/proxy, OAuth, MITM, updater, and browser automation functionality, but inspected behavior is package-aligned or disabled rather than covert exfiltration or persistence.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
npm install postinstall and user-invoked zevai/runtime UI actions
Impact
Installs optional runtime dependencies and runs local router/proxy features when invoked; no confirmed malicious impact.
Mechanism
package-aligned runtime dependency bootstrap and AI provider routing
Rationale
Static inspection found risky primitives, but they are tied to ZevaiRouter's stated local AI router, updater, automation, and proxy features, and the most concerning Claude/Cowork mutation endpoint is disabled by an immediate 403 return. I found no concrete install/import-time exfiltration, destructive payload, dependency-confusion exploit, or unconsented AI-agent control-surface mutation.
Evidence
package.jsoncli/hooks/postinstall.jscli/hooks/sqliteRuntime.jscli/hooks/playwrightRuntime.jscli/hooks/trayRuntime.jscli/hooks/camoufoxRuntime.jscli/cli.jssrc/app/api/cli-tools/cowork-settings/route.jsopen-sse/translator/index.js

Decision evidence

public snapshot
AI called this Clean at 82.0% confidence as Benign with medium false-positive risk.
Evidence for block
  • package.json defines postinstall hook cli/hooks/postinstall.js
  • cli/hooks/sqliteRuntime.js installs better-sqlite3 into ~/.zevai/runtime
  • cli/hooks/playwrightRuntime.js may install playwright and Chromium
  • src/app/api/cli-tools/cowork-settings/route.js contains Claude config mutation code, but POST returns 403 before it
Evidence against
  • No install-time credential/env harvesting or exfiltration found in inspected hooks
  • Runtime npm installs are fixed package-aligned deps for SQLite/tray/browser automation
  • Network use is aligned with AI router/OAuth/provider validation functionality
  • Cowork config mutation path is unreachable because POST immediately returns disabled 403
  • open-sse/translator/index.js dynamic require is a static translator registry
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNativeBindingsNetworkShell
Supply chain
HighEntropyStringsMinifiedObfuscatedUrlStrings
ManifestNo manifest risk signals triggered.
scanned 668 file(s), 4.41 MB of source, external domains: 127.0.0.1, abc-tunnel.us, accounts.google.com, agent.api5.cursor.sh, agentn.api5.cursor.sh, agentrouter.org, ai-gateway.vercel.sh, ai.enally.in, ai.google.dev, aiplatform.googleapis.com, aistudio.google.com, antigravity.google, api-dashboard.search.brave.com, api-inference.huggingface.co, api.ai21.com, api.aimlapi.com, api.anthropic.com, api.assemblyai.com, api.bfl.ai, api.blackbox.ai, api.bytez.com, api.cartesia.ai, api.cerebras.ai, api.cline.bot, api.cloudflare.com, api.cohere.ai, api.commandcode.ai, api.deepgram.com, api.deepinfra.com, api.deepseek.com, api.deno.com, api.dev.runwayml.com, api.elevenlabs.io, api.exa.ai, api.example.com, api.fal.ai, api.firecrawl.dev, api.fireworks.ai, api.freetheai.xyz, api.github.com, api.githubcopilot.com, api.groq.com, api.hyperbolic.xyz, api.inference.net, api.inworld.ai, api.jina.ai, api.kilo.ai, api.kimi.com, api.kluster.ai, api.lepton.ai

Source & flagged code

18 flagged · loading source
package.jsonView file
scripts.postinstall = node cli/hooks/postinstall.js || exit 0
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
Runtime dependency names matching Node built-ins: fs
High
Node Builtin Dependency Squat

Package declares a runtime dependency whose name matches a Node built-in module.

package.jsonView on unpkg
scripts.postinstall = node cli/hooks/postinstall.js || exit 0
Medium
Ambiguous Install Lifecycle Script

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

package.jsonView on unpkg
cli/app/.next-cli-build/server/chunks/42.jsView file
1patternName = private_key_rsa severity = critical line = 1 matchedText = "use str...}}};
Critical
Critical Secret

Package contains a critical-looking secret pattern.

cli/app/.next-cli-build/server/chunks/42.jsView on unpkg · L1
1patternName = private_key_rsa severity = critical line = 1 matchedText = "use str...}}};
Critical
Secret Pattern

RSA private key in cli/app/.next-cli-build/server/chunks/42.js

cli/app/.next-cli-build/server/chunks/42.jsView on unpkg · L1
open-sse/handlers/ttsProviders/localDevice.jsView file
1// Local device TTS — macOS `say` + Windows SAPI + ffmpeg L2: import { execFile } from "node:child_process"; L3: import { promisify } from "node:util";
High
Child Process

Package source references child process execution.

open-sse/handlers/ttsProviders/localDevice.jsView on unpkg · L1
35const { stdout } = await execFileAsync( L36: "powershell.exe", L37: ["-NoProfile", "-NonInteractive", "-WindowStyle", "Hidden", "-Command", script],
High
Shell

Package source references shell execution.

open-sse/handlers/ttsProviders/localDevice.jsView on unpkg · L35
open-sse/translator/index.jsView file
32// Request translators - sync require pattern for bundler L33: require("./request/claude-to-openai.js"); L34: require("./request/openai-to-claude.js");
Medium
Dynamic Require

Package source references dynamic require/import behavior.

open-sse/translator/index.jsView on unpkg · L32
src/mitm/cert/install.jsView file
2const crypto = require("crypto"); L3: const { exec } = require("child_process"); L4: const { execWithPassword, isSudoAvailable } = require("../dns/dnsConfig.js"); ... L7: L8: const IS_WIN = process.platform === "win32"; L9: const IS_MAC = process.platform === "darwin"; ... L34: const pem = fs.readFileSync(certPath, "utf-8"); L35: const der = Buffer.from(pem.replace(/-----[^-]+-----/g, "").replace(/\s/g, ""), "base64"); L36: return crypto.createHash("sha1").update(der).digest("hex").toUpperCase().match(/.{2}/g).join(":"); ... L52: // Verify exact cert bytes match — same CN with different fingerprint = stale cert L53: exec(`security find-certificate -a -c "${ROOT_CA_CN}" -Z /Library/Keychains/System.keychain 2>/dev/null`, { windowsHide: true }, (error, stdout) => { L54: if (error || !stdout) return resolve(false);
Low
Weak Crypto

Package source references weak cryptographic algorithms.

src/mitm/cert/install.jsView on unpkg · L2
cli/src/cli/tray/autostart.jsView file
3const os = require("os"); L4: const { execSync } = require("child_process"); L5: ... L36: } L37: const computed = path.resolve(__dirname, "..", "..", "..", "cli.js"); L38: if (fs.existsSync(computed)) return computed; ... L47: function enableAutoStart(cliPath) { L48: const platform = process.platform; L49: L50: if (!["darwin", "win32", "linux"].includes(platform)) return false; L51: if (platform === "linux" && !process.env.DISPLAY) return false; L52:
Medium
Install Persistence

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

cli/src/cli/tray/autostart.jsView on unpkg · L3
cli/app/src/mitm/server.jsView file
24Private-MAC: `+B.digest().toHex()+`\r L25: `,s};ma.publicKeyToOpenSSH=function(e,t){var a="ssh-rsa";t=t||"";var r=Ce.util.createBuffer();return vr(r,a),Et(r,e.e),Et(r,e.n),a+" "+Ce.util.encode64(r.bytes())+" "+t};ma.private... L26: `);u=c.pop()||"";for(let g of c){let v=g.trim();if(!v||!v.startsWith("data:"))continue;let y=v.slice(5).trim();if(y!=="[DONE]"){process.env.DEBUG_MITM&&Ea(`[SSE in] ${y.slice(0,200... ... L32: `)}catch{}}var od=(()=>{let e=new Uint32Array(256);for(let t=0;t<256;t++){let a=t;for(let r=0;r<8;r++)a=a&1?3988292384^a>>>1:a>>>1;e[t]=a}return e})();function ko(e){let t=42949672... L33: `);t.push({role:"tool",tool_call_id:n.toolUseId||"",content:s})}let r=(e.content||"").trim();return(r||a.length===0)&&t.push({role:"user",content:r}),t}function fd(e){let t=e.toolU... L34: $proc = Start-Process powershell -ArgumentList @(
High
Same File Env Network Execution

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

cli/app/src/mitm/server.jsView on unpkg · L24
24Private-MAC: `+B.digest().toHex()+`\r L25: `,s};ma.publicKeyToOpenSSH=function(e,t){var a="ssh-rsa";t=t||"";var r=Ce.util.createBuffer();return vr(r,a),Et(r,e.e),Et(r,e.n),a+" "+Ce.util.encode64(r.bytes())+" "+t};ma.private... L26: `);u=c.pop()||"";for(let g of c){let v=g.trim();if(!v||!v.startsWith("data:"))continue;let y=v.slice(5).trim();if(y!=="[DONE]"){process.env.DEBUG_MITM&&Ea(`[SSE in] ${y.slice(0,200... ... L32: `)}catch{}}var od=(()=>{let e=new Uint32Array(256);for(let t=0;t<256;t++){let a=t;for(let r=0;r<8;r++)a=a&1?3988292384^a>>>1:a>>>1;e[t]=a}return e})();function ko(e){let t=42949672... L33: `);t.push({role:"tool",tool_call_id:n.toolUseId||"",content:s})}let r=(e.content||"").trim();return(r||a.length===0)&&t.push({role:"user",content:r}),t}function fd(e){let t=e.toolU... L34: $proc = Start-Process powershell -ArgumentList @( ... L37: ) -Verb RunAs -Wait -PassThru -WindowStyle Hidden; L38: if ($proc.ExitCode -ne 0) { throw "Elevated command exited with code $($proc.ExitCode)" } L39: `;return new Promise((r,n)=>{qo(`powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command ${zo(a)}`,{windowsHide:!0},(s,i,o)=>{if(s){let u=o||s.message;u.includes("ca..
High
Command Output Exfiltration

Source combines command execution, command-output handling, and outbound requests; review data flow before blocking.

cli/app/src/mitm/server.jsView on unpkg · L24
cli/cli.jsView file
2Cross-file remote execution chain: cli/cli.js spawns cli/app/src/mitm/server.js; helper contains network access plus dynamic code execution. L2: L3: const { spawn, exec, execSync } = require("child_process"); L4: const path = require("path"); L5: const fs = require("fs"); L6: const https = require("https"); L7: const os = require("os"); ... L16: start() { L17: if (process.stdout.isTTY) { L18: process.stdout.write(`\r${frames[0]} ${currentText}`); L19: interval = setInterval(() => { ... L44: L45: const pkg = require("./package.json");
High
Cross File Remote Execution Context

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

cli/cli.jsView on unpkg · L2
cli/app/src/lib/updater/updater.jsView file
1// Standalone detached updater process. L2: // Spawns `npm i -g <pkg>@latest`, exposes progress via tiny HTTP server. L3: // Survives after parent Next server exits (detached + unref by spawner). L4: L5: const { spawn } = require("child_process"); L6: const http = require("http");
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

cli/app/src/lib/updater/updater.jsView on unpkg · L1
cli/src/cli/tray/tray.ps1View file
path = cli/src/cli/tray/tray.ps1 kind = build_helper sizeBytes = 2581 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

cli/src/cli/tray/tray.ps1View on unpkg
cli/app/.next-cli-build/static/media/ba9851c3c22cd980-s.woff2View file
path = cli/app/.next-cli-[redacted]-s.woff2 kind = high_entropy_blob sizeBytes = 25844 magicHex = [redacted]
High
Ships High Entropy Blob

Package ships high-entropy non-source blobs.

cli/app/.next-cli-build/static/media/ba9851c3c22cd980-s.woff2View on unpkg
cli/app/cli/hooks/sqliteRuntime.jsView file
matchType = previous_version_dangerous_delta matchedPackage = zevairouter@1.0.27 matchedIdentity = npm:emV2YWlyb3V0ZXI:1.0.27 similarity = 0.983 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.

cli/app/cli/hooks/sqliteRuntime.jsView on unpkg
cli/app/.next-cli-build/server/chunks/8971.jsView file
1patternName = private_key_rsa severity = critical line = 1 matchedText = "use str...}}};
Critical
Secret Pattern

RSA private key in cli/app/.next-cli-build/server/chunks/8971.js

cli/app/.next-cli-build/server/chunks/8971.jsView on unpkg · L1

Findings

4 Critical9 High7 Medium6 Low
CriticalCritical Secretcli/app/.next-cli-build/server/chunks/42.js
CriticalPrevious Version Dangerous Deltacli/app/cli/hooks/sqliteRuntime.js
CriticalSecret Patterncli/app/.next-cli-build/server/chunks/42.js
CriticalSecret Patterncli/app/.next-cli-build/server/chunks/8971.js
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processopen-sse/handlers/ttsProviders/localDevice.js
HighShellopen-sse/handlers/ttsProviders/localDevice.js
HighSame File Env Network Executioncli/app/src/mitm/server.js
HighCommand Output Exfiltrationcli/app/src/mitm/server.js
HighCross File Remote Execution Contextcli/cli.js
HighRuntime Package Installcli/app/src/lib/updater/updater.js
HighShips High Entropy Blobcli/app/.next-cli-build/static/media/ba9851c3c22cd980-s.woff2
HighNode Builtin Dependency Squatpackage.json
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumDynamic Requireopen-sse/translator/index.js
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencecli/src/cli/tray/autostart.js
MediumShips Build Helpercli/src/cli/tray/tray.ps1
MediumStructural Risk Force Deep Review
LowScripts Present
LowWeak Cryptosrc/mitm/cert/install.js
LowFilesystem
LowObfuscated
LowHigh Entropy Strings
LowUrl Strings