AI Security Review
scanned 11d ago · by lpm-firewall-aiNo confirmed malicious attack surface. The risky primitives are aligned with a universal server CLI: loading a user app entry, running a child process for watch mode, serving static files, and making user-requested fetches.
Static reason
One or more suspicious static signals were detected.
Trigger
User runs the srvx CLI or imports server adapters.
Impact
No unconsented execution, exfiltration, persistence, or destructive behavior identified.
Mechanism
User-invoked server framework and CLI utilities
Rationale
Static inspection shows package-aligned server and CLI behavior with no lifecycle execution and no hardcoded malicious endpoint or data collection path. Dynamic imports, child_process fork, env-file reads, and fetch are user-invoked features expected for this package type.
Evidence
package.jsonbin/srvx.mjsdist/cli.mjsdist/loader.mjsdist/static.mjsdist/adapters/node.mjsdist/_chunks/_plugins.mjs
Decision evidence
public snapshotAI called this Clean at 91.0% confidence as Benign with low false-positive risk.
Evidence for block
- dist/cli.mjs uses node:child_process fork for dev/watch serve mode, requiring explicit CLI invocation.
- dist/loader.mjs dynamically imports user-selected server entry files.
Evidence against
- package.json has no install/postinstall lifecycle hooks; prepack is publish-time only.
- bin/srvx.mjs only forwards to dist/cli.mjs when the srvx binary is run.
- dist/cli.mjs fetch mode contacts only user-supplied URLs or local loaded handlers, with no hardcoded exfiltration endpoint.
- dist/static.mjs only serves files under the configured static directory and checks path containment.
- No credential harvesting, persistence, destructive writes, or AI-agent control-surface modification found.
Behavioral surface
ChildProcessDynamicRequireEnvironmentVarsFilesystemNetworkShell
HighEntropyStringsUrlStrings
WildcardDependency
Source & flagged code
4 flagged · loading sourcedist/cli.mjsView file
4import { fileURLToPath } from "node:url";
L5: import { fork } from "node:child_process";
L6: import { createReadStream, existsSync, statSync } from "node:fs";
High
372async function forkCLI(args, runtimeArgs) {
L373: const child = fork(fileURLToPath(globalThis.__SRVX_BIN__ || new URL("../bin/srvx.mjs", import.meta.url)), [...args], { execArgv: [...process.execArgv, ...runtimeArgs].filter(Boolea...
L374: child.on("error", (error) => {
High
4Cross-file remote execution chain: dist/cli.mjs spawns dist/loader.mjs; helper contains network access plus dynamic code execution.
L4: import { fileURLToPath } from "node:url";
L5: import { fork } from "node:child_process";
L6: import { createReadStream, existsSync, statSync } from "node:fs";
...
L11: try {
L12: if (!process.env.NODE_ENV) process.env.NODE_ENV = cliOpts.prod ? "production" : "development";
L13: let server;
...
L90: }
L91: async function cliFetch(cliOpts) {
L92: const stdin = cliOpts.stdin || process.stdin;
L93: const stdout = cliOpts.stdout || process.stdout;
L94: const stderr = cliOpts.stderr || process.stderr;
...
L103: if (cliOpts.verbose && loaded.url) {
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/cli.mjsView on unpkg · L4dist/loader.mjsView file
41if (opts.interceptHttpListen !== false) {
L42: const loaded = await interceptListen(() => import(url), opts);
L43: mod = loaded.res;
Medium
Dynamic Require
Package source references dynamic require/import behavior.
dist/loader.mjsView on unpkg · L41Findings
3 High4 Medium4 Low
HighChild Processdist/cli.mjs
HighShelldist/cli.mjs
HighCross File Remote Execution Contextdist/cli.mjs
MediumDynamic Requiredist/loader.mjs
MediumNetwork
MediumEnvironment Vars
MediumWildcard Dependency
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings