registry  /  @ovrdev/cli  /  0.1.0-alpha.22

@ovrdev/cli@0.1.0-alpha.22

Override — the dev control plane: environments, repos, services, tasks

AI Security Review

scanned 12h ago · by lpm-firewall-ai

No confirmed malicious attack surface. Installation only restores execute permission on `node-pty` helper binaries; CLI capabilities require explicit user commands and project configuration.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
npm postinstall or explicit `ovr` CLI commands
Impact
No unconsented exfiltration, remote payload execution, or foreign AI-agent control-surface modification found.
Mechanism
dependency helper permission repair and user-invoked development orchestration
Rationale
The lifecycle hook is narrowly scoped to repairing executable permissions for a package dependency and contains no network or code-execution chain. Scanner persistence labels are explained by normal CLI configuration, key, and service-management features that require explicit user invocation.
Evidence
package.jsonscripts/postinstall.mjsdist/cli/index.jsdist/index-s6rge1qt.jsnode_modules/node-pty/prebuilds/<platform>/spawn-helper

Decision evidence

public snapshot
AI called this Clean at 94.0% confidence as Benign with low false-positive risk.
Evidence for block
  • `package.json` defines a `postinstall` hook.
  • `scripts/postinstall.mjs` chmods only `node-pty` `spawn-helper` binaries.
  • `dist/cli/index.js` can dynamically import user-owned `ovr.config.*` at CLI runtime.
Evidence against
  • Postinstall has no network, shell, payload download, or credential access.
  • Its chmod target is limited to the declared `node-pty` dependency's helper.
  • Claude/shell configuration changes occur only through interactive `ovr bootstrap` confirmations.
  • Runtime network use is local readiness probing or user-configured Git/service URLs.
  • No AI-agent config mutation occurs during installation.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
Manifest
NoLicense
scanned 24 file(s), 462 KB of source, external domains: 127.0.0.1

Source & flagged code

6 flagged · loading source
package.jsonView file
scripts.postinstall = node scripts/postinstall.mjs
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
scripts.postinstall = node scripts/postinstall.mjs
Medium
Ambiguous Install Lifecycle Script

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

package.jsonView on unpkg
dist/cli/index.jsView file
39import * as clack2 from "@clack/prompts"; L40: import { execFileSync as execFileSync3 } from "node:child_process"; L41: import { appendFileSync, existsSync as existsSync7, mkdirSync as mkdirSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync8 } from "node:fs"; ... L54: try { L55: return JSON.parse(readFileSync(answersPath(dir), "utf8")); L56: } catch { ... L106: async function promptAsk(repo, key, spec) { L107: const rl = createInterface({ input: process.stdin, output: process.stderr }); L108: try { ... L115: } L116: process.stderr.write(`? ${repo}: ${spec.question} L117: `);
Critical
Persistence Backdoor

Source writes persistence or remote-access backdoor material.

dist/cli/index.jsView on unpkg · L39
39Trigger-reachable chain: manifest.bin -> dist/cli/index.js L39: import * as clack2 from "@clack/prompts"; L40: import { execFileSync as execFileSync3 } from "node:child_process"; L41: import { appendFileSync, existsSync as existsSync7, mkdirSync as mkdirSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync8 } from "node:fs"; ... L54: try { L55: return JSON.parse(readFileSync(answersPath(dir), "utf8")); L56: } catch { ... L106: async function promptAsk(repo, key, spec) { L107: const rl = createInterface({ input: process.stdin, output: process.stderr }); L108: try { ... L115: } L116: process.stderr.write(`? ${repo}: ${spec.question} L117: `);
Critical
Trigger Reachable Dangerous Capability

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

dist/cli/index.jsView on unpkg · L39
141return null; L142: const mod = await import(pathToFileURL(file).href); L143: const config = mod.default ?? mod;
Medium
Dynamic Require

Package source references dynamic require/import behavior.

dist/cli/index.jsView on unpkg · L141
39import * as clack2 from "@clack/prompts"; L40: import { execFileSync as execFileSync3 } from "node:child_process"; L41: import { appendFileSync, existsSync as existsSync7, mkdirSync as mkdirSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync8 } from "node:fs"; ... L54: try { L55: return JSON.parse(readFileSync(answersPath(dir), "utf8")); L56: } catch { ... L106: async function promptAsk(repo, key, spec) { L107: const rl = createInterface({ input: process.stdin, output: process.stderr }); L108: try { ... L115: } L116: process.stderr.write(`? ${repo}: ${spec.question} L117: `);
Low
Weak Crypto

Package source references weak cryptographic algorithms.

dist/cli/index.jsView on unpkg · L39

Findings

2 Critical1 High5 Medium6 Low
CriticalPersistence Backdoordist/cli/index.js
CriticalTrigger Reachable Dangerous Capabilitydist/cli/index.js
HighInstall Time Lifecycle Scriptspackage.json
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumDynamic Requiredist/cli/index.js
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowScripts Present
LowWeak Cryptodist/cli/index.js
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings
LowNo License