registry  /  @devflow-tools/devflow  /  0.12.0

@devflow-tools/devflow@0.12.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 mutates the consuming project's Claude Code configuration. It installs a wildcard PreToolUse hook that runs package code on every Claude Code tool invocation and sends event input to an environment-configurable telemetry endpoint.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
`npm install @devflow-tools/devflow`, followed by any Claude Code tool use
Impact
Unconsented AI-agent lifecycle execution and potential exfiltration of tool-call inputs
Mechanism
Postinstall Claude Code hook injection with configurable tool-input telemetry
Policy narrative
The postinstall script finds the consuming project, creates `.claude`, and merges a wildcard `PreToolUse` command pointing to package code. On each future Claude Code tool event, the handler reads `tool_name` and `tool_input`, records session metadata, and POSTs the event to `DEVFLOW_API_URL`; failures are cached under the user's home directory for retry. The default endpoint is localhost, but the destination is environment-configurable. This is an unconsented install-time mutation of a foreign AI-agent control surface coupled to a concrete tool-input telemetry path.
Rationale
Source inspection confirms a concrete postinstall AI-agent control-surface hijack and configurable data-upload behavior. The localhost default does not remove the risk because the hook is injected without consent and its endpoint is externally configurable.
Evidence
package.jsonscripts/postinstall.jsdist/hooks/pre-tool-use.jsdist/hooks/hook-client.jsdist/hooks/hook-daemon.jsdist/hooks/post-tool-use.jsdist/hooks/stop.jsdist/plugin/hooks.json.claude/hooks.json~/.devflow/telemetry-cache~/.devflow/session-id~/.devflow/event-map.json
Network endpoints4
127.0.0.1:13337${DEVFLOW_API_URL}/api/telemetry/tool-call${DEVFLOW_API_URL}/api/telemetry/skill-execution/start${DEVFLOW_API_URL}/api/telemetry/sessions

Decision evidence

public snapshot
AI called this Malicious at 98.0% confidence as Malware with low false-positive risk.
Evidence for policy block
  • `package.json` runs `node scripts/postinstall.js`.
  • `scripts/postinstall.js` creates/edits consumer `.claude/hooks.json` during install.
  • It registers wildcard `PreToolUse` command execution of `dist/hooks/pre-tool-use.js`.
  • `pre-tool-use.js` serializes `tool_input` and POSTs it to configurable `DEVFLOW_API_URL`.
  • Failed telemetry is persisted under `~/.devflow/telemetry-cache` for retries.
  • Hook payload also stores session/project metadata in `~/.devflow`.
Evidence against
  • Default telemetry host is loopback: `http://127.0.0.1:13337`.
  • No remote payload download or credential-file harvesting was observed in inspected files.
  • The hook has timeout/fallback behavior, but it remains broadly installed without consent.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsMinifiedUrlStrings
Manifest
NoLicense
scanned 7 file(s), 71.7 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 Ro,{readFileSync,existsSync,mkdirSync,writeFileSync,unlinkSync,statSync,cpSync,readdirSync,rmSync}from'fs';import Hn,{dirname,join,resolve}from'path';import {homedir}from'os... L3: `)}var q,Go,B=de(()=>{Se();q=be.default??be,Go=createRequire(import.meta.url);});function W(e){let o=join(e,".devflow","config.json");if(existsSync(o))try{let n=readFileSync(o,"utf...
High
Child Process

Package source references child process execution.

dist/cli.jsView on unpkg · L1
1#!/usr/bin/env node L2: import Ro,{readFileSync,existsSync,mkdirSync,writeFileSync,unlinkSync,statSync,cpSync,readdirSync,rmSync}from'fs';import Hn,{dirname,join,resolve}from'path';import {homedir}from'os... L3: `)}var q,Go,B=de(()=>{Se();q=be.default??be,Go=createRequire(import.meta.url);});function W(e){let o=join(e,".devflow","config.json");if(existsSync(o))try{let n=readFileSync(o,"utf... ... 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 O(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 oo(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