postinstall-guardian
v0.1.1
Published
Scan node_modules for preinstall/install/postinstall scripts (the #1 npm supply-chain attack vector) and gate CI on any that aren't explicitly approved.
Maintainers
Readme
postinstall-guardian
Scan node_modules for preinstall/install/postinstall scripts — the
most common npm supply-chain attack vector (a compromised or typosquatted
package runs arbitrary code the moment someone runs npm install) — and gate
CI on any that aren't explicitly approved.
Why not just npm audit?
npm audit only flags packages with a reported CVE. A malicious install
script in a brand-new or typosquatted package has no CVE yet — that's exactly
how the recent high-profile npm supply-chain compromises worked. This tool
doesn't judge whether a script is malicious (it can't); it makes sure a human
looks at every install script before it's allowed to run unreviewed in CI.
How it works
postinstall-guardian scanwalksnode_modules(including nested/hoisted copies) and lists every package with an install-type script.- Compare that list against a baseline file (
.postinstall-guardian.json, committed to your repo) of package versions you've already reviewed and approved. postinstall-guardian ciexits non-zero if anything isn't in the baseline — so a new or bumped dependency with a new install script fails the build until someone reviews and approves it.
A version bump automatically drops out of the baseline and gets re-flagged, since a new version can ship a different script than the one you approved.
Install
npm install --save-dev postinstall-guardianCLI
postinstall-guardian scan
postinstall-guardian scan --dir . --report report.mdLists every install-type script found and marks which ones aren't yet
approved. Exit code is always 0 — use ci for a gating exit code.
postinstall-guardian approve
postinstall-guardian approveAdds every currently-found install script to .postinstall-guardian.json.
Review the scan output before running this — approving is how you tell
the tool "I looked at this command and it's fine."
postinstall-guardian ci
postinstall-guardian ci --report postinstall-guardian-report.mdScans, writes a report, and exits 1 if any install script isn't in the baseline. This is the command to run in CI.
postinstall-guardian init-workflow
postinstall-guardian init-workflow
# writes .github/workflows/postinstall-guardian.ymlWrites a workflow that runs on every push/PR to main (new install scripts
arrive with dependency changes, not on a calendar) plus a daily cron as a
backstop for unpinned version ranges resolving to a new version between
deploys. It installs with npm ci --ignore-scripts so CI never executes the
scripts it's auditing.
Library API
import { scan, mergeIntoBaseline, writeBaseline, readBaseline } from 'postinstall-guardian';
const result = await scan('./my-project');
if (result.unapproved.length > 0) {
console.log(`${result.unapproved.length} unreviewed install script(s)`);
}Baseline file format
{
"approved": ["[email protected]", "[email protected]"]
}Commit .postinstall-guardian.json to version control — reviewing and
approving a new script is meant to happen in a PR, same as any other code
change.
Limitations
- Only npm's
node_moduleslayout is supported (pnpm's symlink layout is deduped via realpath, but scoped/aliased pnpm structures aren't specially handled). - This tool surfaces scripts for human review — it does not analyze whether a script is actually malicious.
