AI Security Review
scanned 11d ago · by lpm-firewall-aiNo confirmed malicious attack surface was established. The risky primitives are user-invoked infrastructure features: shell integration, Doppler env loading, release/worktree automation, and managed agent guidance updates.
Static reason
No blocking static signals were detected.; previous stored version diff introduced dangerous source
Trigger
User runs infra-kit CLI commands, starts the MCP server, or runs `infra-kit init`; no install-time trigger exists.
Impact
Can mutate local shell config, repo guidance files, worktrees, and release/deploy systems when explicitly invoked and configured; no evidence of covert execution or exfiltration.
Mechanism
Package-aligned CLI/MCP automation with guarded file writes and external CLI/API calls
Rationale
Source inspection shows dangerous-looking primitives, but they are documented, user-invoked infra-kit functionality rather than install/import-time malware or covert exfiltration. The scanner's persistence and AI-agent-control hints map to explicit `infra-kit init` behavior with managed markers, backups, and no lifecycle trigger.
Evidence
package.jsonsrc/entry/cli.tssrc/entry/mcp.tssrc/lib/command-catalog/command-catalog.tssrc/commands/init/init.tssrc/commands/init/agent-files.tssrc/commands/env-load/env-load.tssrc/lib/env-autoload/env-autoload.tssrc/lib/package-validator/loader/config-loader.ts~/.zshrc~/.infra-kit/infra-kit.json~/.infra-kit/infra-kit.example.jsonc~/.infra-kit/vendor.example.jsoncCLAUDE.mdAGENTS.md$XDG_CACHE_HOME/infra-kit/<session>/env-load.sh
Decision evidence
public snapshotAI called this Clean at 86.0% confidence as Benign with medium false-positive risk.
Evidence for block
- src/commands/init/init.ts writes a managed zsh shell block and ~/.infra-kit config only when `infra-kit init` is run.
- src/commands/init/agent-files.ts writes managed CLAUDE.md guidance and migrates legacy AGENTS.md on explicit init.
- src/commands/env-load/env-load.ts downloads Doppler secrets and writes env-load.sh under a per-session cache for sourcing.
- src/lib/package-validator/loader/config-loader.ts dynamically imports project infra-kit.config.ts for package audit configuration.
Evidence against
- package.json has no preinstall/install/postinstall/prepare lifecycle hooks.
- src/entry/cli.ts excludes init/env commands from automatic env autoload; autoload is config-gated and user-invoked via CLI shell integration.
- src/lib/command-catalog/command-catalog.ts explicitly excludes init, vendor-sync, vendor-manifest, release-deliver, and worktrees-remove from MCP exposure.
- src/commands/env-load/env-load.ts validates Doppler output as KEY=value, caps size, and writes mode 0600 cache files.
- src/commands/init/agent-files.ts refuses symlink destinations and backs up files before managed edits.
- No hardcoded exfiltration endpoint or credential harvesting beyond user-requested Doppler/Jira/GitHub workflow functions was found.
Behavioral surface
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShell
HighEntropyStringsMinifiedUrlStrings
NoLicense
Source & flagged code
3 flagged · loading sourcesrc/lib/package-validator/loader/config-loader.tsView file
60L61: const imported = (await import(moduleUrl)) as { default?: unknown }
L62: const rawExport = imported.default
Medium
Dynamic Require
Package source references dynamic require/import behavior.
src/lib/package-validator/loader/config-loader.tsView on unpkg · L60dist/chunk-W4QG2W7G.jsView file
1import{b as Pe,c as Et,d as Tt,e as dr,f as un}from"./chunk-WA4BQRDC.js";import gn from"node:process";import $t from"pino";import si from"pino-pretty";var fn="/tmp/mcp-infra-kit.lo...
L2: `).filter(Boolean),o={release:di,feature:mi};return t.map(o[e]).filter(n=>n!==null)},bn=e=>{let r=e.trimEnd();if(!r.endsWith("]"))return null;let t=r.lastIndexOf("[");if(t===-1)ret...
L3: ${e.packageName} \u2014 ${r}`);for(let t of e.checks){let o=t.status==="pass"?"[PASS]":"[FAIL]";a.info(` ${o} ${t.name}: ${t.message}`)}},Tn=async(e={})=>{let r=await Ii(e),t=[];f...
...
L6: ${r}
L7: ${t}`,gr=({content:e,body:r,startMarker:t,endMarker:o,placement:n="replace-in-place"})=>{let s=$n(t,r,o),i=He(e,t,o);if(n==="replace-in-place"&&i){let p=e.indexOf(t),d=e.indexOf(o)...
L8: ${s}
L9: `:`${s}
L10: `};import O from"node:fs";import vr from"node:path";import Kt from"node:fs/promises";import Ni from"node:os";import hr from"node:path";import{z as y}from"zod";var In="infra-kit.jso...
L11: `),An=e=>{if(O.existsSync(e)&&O.lstatSync(e).isSymbolicLink())throw new Error(`Refusing to write ${e} because the destination is a symlink`)},Nn=e=>{let r=new Date().toISOString()....
...
L61: // "provider": "jira",
L6
Medium
Install Persistence
Source writes installer persistence such as shell profile or service configuration.
dist/chunk-W4QG2W7G.jsView on unpkg · L1src/lib/constants/constants.tsView file
•matchType = previous_version_dangerous_delta
matchedPackage = infra-kit@0.1.125
matchedIdentity = npm:aW5mcmEta2l0:0.1.125
similarity = 0.917
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.
src/lib/constants/constants.tsView on unpkgFindings
1 Critical5 Medium5 Low
CriticalPrevious Version Dangerous Deltasrc/lib/constants/constants.ts
MediumDynamic Requiresrc/lib/package-validator/loader/config-loader.ts
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencedist/chunk-W4QG2W7G.js
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings
LowNo License