registry  /  substrate-ai  /  0.20.142

substrate-ai@0.20.142

Substrate — multi-agent orchestration daemon for AI coding agents

AI Security Review

scanned 3h ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. No confirmed malicious install-time or import-time attack surface was found. The package does contain first-party AI orchestration features that can expose project files and shell execution to configured model providers when users invoke the pipeline/direct backend.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
Explicit CLI use such as substrate run/factory direct backend or substrate init --install-user-scope
Impact
Remote model providers can drive local file edits and shell commands within the configured project; substrate-owned .codex/.claude artifacts may be created or pruned by explicit setup commands.
Mechanism
user-invoked agent orchestration with file/shell tools and first-party prompt/skill scaffolding
Rationale
Static inspection supports a warning for first-party agent extension setup and dangerous user-invoked AI tooling, but not a publish block: no lifecycle hook, import-time payload, credential theft, or unconsented broad agent-control mutation was found. The scanner's malicious label appears to conflate package-aligned orchestration features with covert attack behavior.
Evidence
package.jsondist/cli/index.jsdist/run-DHHryElL.jsdist/manifest-read-BgZ6mR5R.jsdist/index.js.claude/commands.claude/skills.codex/prompts.codex/skills~/.codex/prompts~/.codex/skills
Network endpoints3
api.anthropic.comapi.openai.com/v1generativelanguage.googleapis.com

Decision evidence

public snapshot
AI called this Suspicious at 86.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • dist/run-DHHryElL.js exposes read_file/write_file/shell/grep/glob tools to LLM tool calls in direct backend
  • dist/run-DHHryElL.js sends prompts/tool schemas to Anthropic/OpenAI/Gemini endpoints using env API keys
  • dist/cli/index.js can scaffold .claude and .codex prompts/skills; --install-user-scope writes namespaced content to ~/.codex
  • dist/cli/index.js prunes only substrate/bmad-owned prompt/skill entries before copying replacements
Evidence against
  • package.json has no preinstall/install/postinstall lifecycle hooks
  • dist/cli/index.js main only runs when invoked as CLI, not on package import
  • Direct backend requires explicit pipeline/factory execution and provider API key env vars
  • User-scope Codex install is gated by explicit --install-user-scope flag
  • No credential harvesting or exfiltration endpoint beyond configured model provider APIs found
  • No broad foreign AI-agent control-surface mutation at npm install time found
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsEvalFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 30 file(s), 2.82 MB of source, external domains: ai.google.dev, api.anthropic.com, api.openai.com, claude.ai, docs.dolthub.com, generativelanguage.googleapis.com, git-scm.com, github.com, json-schema.org, json.schemastore.org, raw.githubusercontent.com, registry.npmjs.org

Source & flagged code

9 flagged · loading source
dist/manifest-read-BgZ6mR5R.jsView file
8import { existsSync, promises, readFileSync, readdirSync, statSync } from "node:fs"; L9: import { execSync, spawn } from "node:child_process"; L10: import * as path$2 from "node:path";
High
Child Process

Package source references child process execution.

dist/manifest-read-BgZ6mR5R.jsView on unpkg · L8
2129detached: true, L2130: shell: true, L2131: stdio: [
High
Shell

Package source references shell execution.

dist/manifest-read-BgZ6mR5R.jsView on unpkg · L2129
dist/run-DHHryElL.jsView file
matchType = previous_version_dangerous_delta matchedPackage = substrate-ai@0.20.139 matchedIdentity = npm:c3Vic3RyYXRlLWFp:0.20.139 similarity = 0.923 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/run-DHHryElL.jsView on unpkg
16import { accessSync, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, unwatchFile, watchFile, writeFileSync } from "node:fs... L17: import { exec, execFile, execFileSync, execSync, spawn } from "node:child_process"; L18: import * as path$5 from "node:path"; ... L5782: if (existsSync(profilePath)) try { L5783: const raw = readFileSync(profilePath, "utf-8"); L5784: const parsed = yaml.load(raw); ... L35920: apiKey; L35921: baseUrl; L35922: anthropicVersion; ... L37328: "", L37329: "Available tools:", L37330: "- read_file: Read file contents with optional line range (offset/limit)",
High
Remote Agent Bridge

Source exposes local file and command tools to a remote model endpoint.

dist/run-DHHryElL.jsView on unpkg · L16
15833try { L15834: execSync(`npm install ${missingPkg}`, { L15835: cwd: resolvedRoot,
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

dist/run-DHHryElL.jsView on unpkg · L15833
31881try { L31882: var makeValidate = new Function("self", "RULES", "formats", "root", "refVal", "defaults", "customRules", "equal", "ucs2length", "ValidationError", sourceCode); L31883: validate$1 = makeValidate(self, RULES, formats$2, root, refVal, defaults$2, customRules, equal, ucs2length, ValidationError);
Low
Eval

Package source references a known benign dynamic code generation pattern.

dist/run-DHHryElL.jsView on unpkg · L31881
dist/cli/index.jsView file
1501try { L1502: const _require = createRequire(join(fromDir, "synthetic.js")); L1503: const pkgJsonPath = _require.resolve("bmad-method/package.json");
Medium
Dynamic Require

Package source references dynamic require/import behavior.

dist/cli/index.jsView on unpkg · L1501
dist/dist-DiNK6QOD.jsView file
3package = substrate-ai; repositoryIdentity = substrate; dependency = js-yaml L3: import { EventEmitter } from "node:events"; L4: import yaml, { dump, load } from "js-yaml"; L5: import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
High
Copied Package Dependency Bridge

Package metadata claims a different repository identity while copied source loads a runtime dependency bridge.

dist/dist-DiNK6QOD.jsView on unpkg · L3
dist/cli/templates/statusline.shView file
path = dist/cli/templates/statusline.sh kind = build_helper sizeBytes = 565 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

dist/cli/templates/statusline.shView on unpkg

Findings

1 Critical5 High5 Medium5 Low
CriticalPrevious Version Dangerous Deltadist/run-DHHryElL.js
HighChild Processdist/manifest-read-BgZ6mR5R.js
HighShelldist/manifest-read-BgZ6mR5R.js
HighRemote Agent Bridgedist/run-DHHryElL.js
HighCopied Package Dependency Bridgedist/dist-DiNK6QOD.js
HighRuntime Package Installdist/run-DHHryElL.js
MediumDynamic Requiredist/cli/index.js
MediumNetwork
MediumEnvironment Vars
MediumShips Build Helperdist/cli/templates/statusline.sh
MediumStructural Risk Force Deep Review
LowScripts Present
LowEvaldist/run-DHHryElL.js
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings