Protect dependency installation process with allow-scripts
@lavamoat/allow-scripts
is a CLI tool for instructing your package manager to execute only the dependency lifecycle hooks specified in an allowlist.
Prerequisites
- Node.js LTS
- One of the following package managers:
- npm v8.0.0+
- Yarn v1.22.0+
- Yarn Berry v3 or above
Install
- npm:
npm i -D @lavamoat/allow-scripts
- Yarn:
yarn add -D @lavamoat/allow-scripts
Note that installation of the dependency is likely to cause your other dependencies to be installed. You could install @lavamoat/allow-scripts
globally and use it to set up a project without triggering installing dependencies before the setup and the allowlist is in place.
Setup
Initialization
The setup
command will initialize your project for use with @lavamoat/allow-scripts
.
- npm:
npm exec allow-scripts setup
- Yarn:
yarn allow-scripts setup
Configuration
Configuration can be done automatically or manually.
Automatic Allow-listing
The auto
command will generate and write a configuration to the lavamoat
property of package.json
.
- npm:
npm exec allow-scripts auto
- Yarn:
yarn allow-scripts auto
Manual Allow-listing
@lavamoat/allow-scripts
’s configuration is stored in the lavamoat
property of package.json
within its allowScripts
property.
The value is of type Record<PackageName, boolean>
where PackageName
is a dependency which is either allowed or disallowed to run lifecycle scripts. To allow script execution, use a value of true
; to disallow, use a value of false
.
Items missing from the list will cause a warnings so that you know when you might need to add a newly installed item to the list.
Example Configuration
Running Lifecycle Scripts
When invoked without a command (or with the run
command), allow-scripts
will execute all lifecycle scripts for the packages specified in @lavamoat/allow-scripts
’s configuration:
- npm:
npm exec allow-scripts run
- Yarn:
yarn allow-scripts run
allow-scripts
will fail if it detects dependencies attempting to run scripts which haven’t yet been configured; you will be advised to run allow-scripts auto
to rectify the situation.
Yarn plugin
To comfortably work with Yarn Berry (specifically yarn v3 or above) it’s recommended that you use a simple plugin to execute allow-scripts
after installation.
Yarn plugins are installed via public URLs.
Show Configured Packages
Use the list
command to print information about configured packages and scripts, specifying allowed and disallowed packages.
- npm:
npm exec allow-scripts list
- Yarn:
yarn allow-scripts list
Usage Tips
Consider adding a setup
lifecycle script for all your post-install steps. This can be just a regular script (no magic needed!). Also, it is a good place to add other post-processing commands you want to use.
In the future, when you add additional post-processing scripts, e.g. husky
, you can add them to this setup
script.
Mitigating bin script confusion
Bin script confusion is a shell injection attack (wiki) where a dependency causes a malicious script to run by declaring a bin
script (in package.json
) matching an executable in the user’s PATH
. ignore-scripts
does not protect against this attack.
To enable protection against bin script confusion, use the --experimental-bins
flag when executing allow-scripts
.
What does --experimental-bins
do?
allow-scripts setup
will add a new configuration option to your project’s package manager RC file (.npmrc
/.yarnrc
) to disable automatic linkingbin
scriptsallow-scripts auto
will generate an allowlist ofbin
scripts allowed for executionallow-scripts run
will link only the allowed scripts and replace disallowed scripts with a trivial executable that exits with a non-zero exit code.
When a disallowed bin
script is attempted to be executed, the command will fail with an error providing guidance.