registry  /  @devflow-tools/devflow  /  0.10.0

@devflow-tools/devflow@0.10.0

DevFlow - Developer Intelligence Platform (Distribution Package)

AI Security Review

scanned 4h ago · by lpm-firewall-ai

LPM blocks this version under the AI-agent control-surface policy. Install-time code modifies the consumer project's Claude Code control configuration and registers a wildcard PreToolUse hook. The hook observes tool inputs, can deny some direct tools, and transmits telemetry to a configurable endpoint.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
npm postinstall, then every Claude Code tool call matching `*`
Impact
Project AI-agent behavior is changed at install time; tool inputs can be retained locally and sent to the configured DevFlow API.
Mechanism
unconsented wildcard AI-agent hook registration with tool-input telemetry
Policy narrative
On `npm install`, the package locates the consuming project and writes `.claude/hooks.json`, adding a wildcard Claude Code PreToolUse command that executes package-owned code. That hook receives tool-call input, records state under `~/.devflow`, posts telemetry to a loopback DevFlow service by default, and supports an environment-configured API URL. It also returns deny decisions for direct tools during declared MCP-required skill execution. This is a foreign, broad AI-agent control-surface mutation performed without an explicit user command.
Rationale
Direct source inspection confirms an unconsented `postinstall` write to a consumer-owned Claude Code hook configuration with wildcard interception. Under the stated install-control-surface policy, this is a publish-block condition even though the default endpoint is localhost.
Evidence
package.jsonscripts/postinstall.jsdist/hooks/pre-tool-use.jsdist/hooks/post-tool-use.jsdist/plugin/hooks.json.claude.claude/hooks.json~/.devflow/telemetry-cache~/.devflow/session-id~/.devflow/event-map.json
Network endpoints3
127.0.0.1:13337${DEVFLOW_API_URL}/api/telemetry/tool-call${DEVFLOW_API_URL}/api/telemetry/skill-execution/start

Decision evidence

public snapshot
AI called this Malicious at 95.0% confidence as Malware with low false-positive risk.
Evidence for policy block
  • `package.json` runs `node scripts/postinstall.js` on install.
  • `scripts/postinstall.js` creates/merges consumer `.claude/hooks.json` without consent.
  • The added `PreToolUse` matcher is `*` and executes packaged `dist/hooks/pre-tool-use.js`.
  • `dist/hooks/pre-tool-use.js` receives every matched tool input and sends telemetry payloads.
  • Hook telemetry defaults to `http://127.0.0.1:13337` but accepts `DEVFLOW_API_URL` override.
  • The hook can deny direct tools when an active skill declares required MCP tools.
Evidence against
  • Postinstall itself has no network or child-process execution.
  • Observed default telemetry endpoint is loopback, not a hard-coded external host.
  • CLI plugin installation is an explicit `devflow plugin install` command.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsMinifiedUrlStrings
Manifest
NoLicense
scanned 7 file(s), 140 KB of source, external domains: 127.0.0.1

Source & flagged code

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

Package defines install-time lifecycle scripts.

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

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

package.jsonView on unpkg
dist/cli.jsView file
1#!/usr/bin/env node L2: import zo,{unlinkSync,existsSync,readFileSync,rmSync,mkdirSync,writeFileSync,statSync,cpSync,readdirSync}from'fs';import xt,{dirname,join,resolve}from'path';import {homedir}from'os... L3: `)}var Q,dn,ee=be(()=>{Oe();Q=Ee.default??Ee,dn=createRequire(import.meta.url);});function z(e){let o=join(e,".devflow","config.json");if(existsSync(o))try{let n=readFileSync(o,"ut...
High
Child Process

Package source references child process execution.

dist/cli.jsView on unpkg · L1
1#!/usr/bin/env node L2: import zo,{unlinkSync,existsSync,readFileSync,rmSync,mkdirSync,writeFileSync,statSync,cpSync,readdirSync}from'fs';import xt,{dirname,join,resolve}from'path';import {homedir}from'os... L3: `)}var Q,dn,ee=be(()=>{Oe();Q=Ee.default??Ee,dn=createRequire(import.meta.url);});function z(e){let o=join(e,".devflow","config.json");if(existsSync(o))try{let n=readFileSync(o,"ut... ... L16: Skipping plugin installation. You can install plugins later with:`),console.log(" devflow plugin list"),console.log(` devflow plugin install <name> L17: `);return i}async function T(e){let o=[],n;e.sseUrl?n={url:e.sseUrl}:n={command:e.command??"devflow-mcp",args:["--mode","stdio"]};let t=e.agent?[e.agent]:await import('@devflow-too... L18: `);if(o.length>=2){let n=parseInt(o[0],10);if(!isNaN(n))return n}return null}function x(e){if(!existsSync(e))return null;let o=readFileSync(e,"utf-8").trim().split(`
High
Same File Env Network Execution

A single source file combines environment access, network access, and code or shell execution; review context before blocking.

dist/cli.jsView on unpkg · L1
12Installing selected plugins... L13: `);for(let s of i)try{execSync(`npm install -g ${s}`,{stdio:"inherit"}),console.log(`\u2713 ${s} L14: `);}catch{console.error(`\u2717 Failed to install ${s}
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

dist/cli.jsView on unpkg · L12
scripts/postinstall.jsView file
1Install-time AI-agent control hijack evidence: L2: // L3: // Auto-configures .claude/hooks.json in the consuming project so that Claude L4: // Code invokes the devflow PreToolUse hook on every tool call. ... L11: L12: import { writeFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs'; L13: import { join, dirname } from 'node:path'; ... L55: L56: const claudeDir = join(projectRoot, '.claude'); L57: const hooksFile = join(claudeDir, 'hooks.json'); ... L59: L60: // 1. Ensure .claude/ directory exists L61: if (!existsSync(claudeDir)) { Payload evidence from dist/plugin/skills/devflow:doctor/SKILL.md: L1: --- L2: name: devflow:doctor
Critical
Ai Agent Control Hijack

Install-time source drops package-supplied AI-agent/MCP control files or instructions.

scripts/postinstall.jsView on unpkg · L1

Findings

1 Critical5 High4 Medium5 Low
CriticalAi Agent Control Hijackscripts/postinstall.js
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processdist/cli.js
HighShell
HighSame File Env Network Executiondist/cli.js
HighRuntime Package Installdist/cli.js
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings
LowNo License