So you've heard about supply chain security? You should no longer want to run npm ci
without the --ignore-scripts
flag. If you still need more convincing - I made a package that makes typescript compiler inject malicious code to your application. See this video for more
Now with the good advice to always run npm ci --ignore-scripts
all that's left is to start using it. But wait! My app no longer works! Some of these scripts were necessary after all...
All you need to do is npm rebuild packagename
. If you know which package needs its scripts to run.
That's the problem with security best practices - there's always convenience that you need to give away. But that's where I come in! I enjoy making security best practices easier to deploy in your team. (That's why I wrote npm-audit-resolver but that's a different story)
--ignore-scripts
and no regrets
Figuring out which of your packages actually need their postinstall scripts is not a candidate to make the list of "top 5 moments at work". I bet you'll be happy to hear there's a tool to do it for you.
can-i-ignore-scripts
is a commandline utility that scans your node_modules folder and lists all packages with scripts that run on installation. It then checks against a collection of known packages whose scripts were already evaluated before and lists suggestions.
You can use the suggestions to quickly choose which scripts to run after the installations have finished.
There's nothing wrong with accepting some scripts you're not sure about. The goal of having an allowlist is to avoid running a script that was maliciously added where it wasn't before. The sooner you introduce --ignore-scripts
to your app the better. Even if that means adding exceptions for ALL existing packages.
Quick roll out in your project? Here you go:
npm ci --ignore-scripts
npx can-i-ignore-scripts
█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
▄▄· ▄▄▄· ▐ ▄ ▄ ▪ ▄▄ ▐ ▄ ▄▄▄ ▄▄▄ ▄▄▄▄·
▐█ ▌ ▐█ ▀█ ·█▌▐█ ██ ██ ▐█ ▀ █▌▐█ ▐▄ █· █ ▀· .▀ .█▌
██ ▄▄▄█▀▀█ ▐█▐▐▌ ▐█· ▐█· ▄█ ▀█▄ ▐█▐▐▌ ▄█▀▄ ▐▀▀▄ ▐█▀ ▄█▀▀▀·
▐███▌▐█ ▪▐▌██▐█▌ ▐█▌ ▐█▌ ▐█▄ ▐█ ██▐█▌▐█▌.▐▌▐▄ █▌▐█▄▄▄▌ ▀
·▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ ▀▀▀ ·▀▀▀▀ ▀▀ █▪ ▀█▄▀▪.▀ ▀ ▀▀▀ ▀
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
Found following packages with scripts:
[ ignore ] 'pre-commit' has scripts but they can be ignored
reason: used in local development
[ ignore ] 'core-js' has scripts but they can be ignored
reason: funding
[ keep ] 'grpc' needs its scripts to run
[ keep ] 'bignum' needs its scripts to run
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
What now? Run rebuild after 'npm ci --ignore-scripts' to trigger scripts you need to keep.
A suggestion to get you started:
npm rebuild bignum grpc
█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
Then take a look at the recommendations and add the rebuild line after the installation in CI
npm rebuild bignum grpc
Go hack yourself
Don't know if postinstall scripts actually run in your CI? Or maybe you need to convince someone it'a an issue? Hack yourself by installing @naugtur/pentest-my-ci
as your dev dependency. It contains a preinstall script that stops the CI and tries to scare the reader of the logs a bit.
Top comments (0)