AI Security Review
scanned 7d ago · by lpm-firewall-aiNo confirmed malicious attack surface was established. The package has high-privilege plugin-manager behavior, but inspected behavior matches its documented OpenCode/Claude plugin updater role.
Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
User invokes plugin-updater CLI or app imports the plugin entry during configured plugin startup.
Impact
Can update/build/deploy configured plugins and write app plugin/command config; no source evidence of covert exfiltration or attacker-controlled endpoint.
Mechanism
Documented plugin lifecycle manager using git/npm, config writes, command deployment, and optional plugin daemon startup
Rationale
Static inspection shows dangerous primitives, but they are exposed as the documented plugin lifecycle manager and act on configured plugin entries or explicit CLI actions. I found no covert endpoint, credential/file harvesting, install-time execution, or unconsented AI-agent control mutation sufficient to classify this as malicious.
Evidence
package.jsondist/index.jsdist/cli.jsdist/npm.jsdist/git.jsdist/deploy.jsdist/daemon.jsdist/syncbridge.jsdist/commands.jslib/core.jsREADME.mddist/config.jsdist/env.js
Network endpoints4
127.0.0.1:<daemon.port>/healthgithub.com/intisy-ai/plugin-updater.gitgithub.com/intisy-ai/<plugin>opencode.ai/config.json
Decision evidence
public snapshotAI called this Clean at 78.0% confidence as Benign with high false-positive risk.
Evidence for block
- dist/index.js auto-activates on import unless PLUGIN_UPDATER_LIBRARY_MODE/ACTIVATION is set.
- dist/cli.js init writes OpenCode plugin entries or Claude SessionStart hook with npx -y plugin-updater@latest.
- dist/git.js and dist/npm.js run git/npm commands for configured plugins; arguments are not shell-escaped.
- dist/deploy.js can import deployed plugin files and start plugin-declared daemons.
Evidence against
- package.json has only prepublishOnly; no install/postinstall lifecycle execution.
- README.md describes plugin lifecycle management, auto-run hooks, git/npm updates, and command deployment as package purpose.
- Network activity is package-aligned: git/npm commands for configured plugin names/URLs and localhost daemon health checks.
- No credential harvesting, secret scanning, external exfiltration endpoint, persistence outside documented app hooks, or destructive behavior beyond managed plugin dirs found.
- dist/cli.js control-surface writes are user-invoked init/add/remove actions; import-time earlyLaunch operates from app plugin configuration.
Behavioral surface
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShell
HighEntropyStringsUrlStrings
Source & flagged code
4 flagged · loading sourcedist/npm.jsView file
3import os from "os";
L4: import { execSync } from "child_process";
L5: import { isOpencodeHookInvocation } from "./env.js";
High
82}
L83: execSync(`npm install -g ${name}`, { stdio: "pipe", timeout: getNpmTimeoutMs() });
L84: writeLog(`Installed npm plugin: ${name}`);
High
Runtime Package Install
Package source invokes a package manager install command at runtime.
dist/npm.jsView on unpkg · L82dist/syncbridge.jsView file
29try {
L30: const bridge = (await import(pathToFileURL(libPath).href));
L31: if (typeof bridge.syncPlugins !== "function") {
Medium
Dynamic Require
Package source references dynamic require/import behavior.
dist/syncbridge.jsView on unpkg · L29dist/daemon.jsView file
•matchType = previous_version_dangerous_delta
matchedPackage = plugin-updater@1.4.3
matchedIdentity = npm:cGx1Z2luLXVwZGF0ZXI:1.4.3
similarity = 0.615
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.
dist/daemon.jsView on unpkgFindings
1 Critical3 High4 Medium5 Low
CriticalPrevious Version Dangerous Deltadist/daemon.js
HighChild Processdist/npm.js
HighShell
HighRuntime Package Installdist/npm.js
MediumDynamic Requiredist/syncbridge.js
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings