@lavamoat/allow-scripts
v5.0.1
Published
A tool for running only the dependency lifecycle hooks specified in an allowlist.
Readme
@lavamoat/allow-scripts
A tool for running only the dependency lifecycle hooks specified in an allowlist.
For an overview of LavaMoat tools see the main README
Usage
@lavamoat/allow-scripts increases your project's security posture by first denying all lifecycle scripts from running, then allowing the ones you actually need. The workflow looks like this:
- Run
allow-scripts setuponce per project to opt-out of running scripts - Run
allow-scripts autoto populate or update the allowlist (configured inpackage.json) - Run
allow-scripts runafter every install to run the lifecycle scripts
We recommend using the globally installed @lavamoat/allow-scripts for initial the initial setup. Thereafter, install it as a project-local development dependency to enable contributors to execute allowed scripts.
Install globally
npm i -g @lavamoat/allow-scriptsBe sure to include the @lavamoat/ namespace in the package name.
Now without triggering an installation in the project you're setting up, you can go to the project folder and run:
allow-scripts setupAnd proceed to the Configure section
Project-local installation
Adds the package to start using it in your project. be sure to include the @lavamoat/ namespace in the package name.
Use any of the following:
npm i -D @lavamoat/allow-scripts
yarn add -D @lavamoat/allow-scripts
pnpm add -D @lavamoat/allow-scriptsIn the following steps you will continue using yarn or npx --no-install if you've installed locally. Local installation is also directly callable in your project's "scripts" in package.json
Example
yarn allow-scripts setup
npx --no-install allow-scripts setup[!WARNING]
If
@lavamoat/allow-scriptsis not already installed,npxwill prompt to download and run packageallow-scripts(missing the@lavamoatscope) which is a different package. We suggest usingnpx --no-installto prevent accidents.
Setup
allow-scripts setupAdds (or updates) a .yarnrc or .npmrc (depending on which lockfile is present) file in the current package and appends ignore-scripts=true.
pnpm ignores scripts by default, but the .npmrc file is generated by default. It's worth keeping in case someone goes for npm install before they notice pnpm is used in the repo.
Immediately after creating the configuration file, allow-scripts setup adds the devDependency @lavamoat/preinstall-always-fail. It is intended to remain disallowed. Adding this package to a project mitigates against accidentally running any lifecycle scripts by throwing an error during the preinstall script execution in case someone deletes the .npmrc
Populate the allowlist
allow-scripts auto generates and writes a configuration into your package.json, setting new policies to false (deny) by default.
After execution, you may enable packages' lifecycle scripts by setting the associated policies to true (allow).
allow-scripts autoConfiguration goes in package.json
{
"lavamoat": {
"allowScripts": {
"keccak#3.0.4": false,
"rezeplayer>core-js#3.49.0": false
}
}
}If allowScripts has an item set to true, the lifecycle scripts of that package will be executed in the run phase if the currently installed version matches.
[!NOTE]
allow-scriptsis pinning versions of the dependencies with lifecycle since v5.- Items set to
falsewill be updated viaallow-scripts autoto the current detected version.- To avoid churn in the list, you can remove the
#versionsuffix from a disallowed item and it will be denied regardless of version.- Versions are mandatory for allowed packages in case of maintainer compromise.
- You can opt out of this behavior with the
--skip-versionsflag on bothautoandrun.
[!TIP]
While you can configure all install scripts that you've been running to date as allowed, it's best to limit the number of them in case a package with pre-existing install script gets exploited. To determine which packages' scripts can be safely ignored, try can-i-ignore-scripts.
Run
Run all lifecycle scripts for the packages specified in package.json
allow-scripts runIt will fail if it detects dependencies which haven't been set up during configuration of the package. You will be advised to run yarn allow-scripts auto.
List
Alias: debug
Prints all information allow-scripts uses to populate and run the allowed scripts.
allow-scripts listImproving your Workflow
Consider adding a setup npm script for all your post-install steps to ensure the running of your allowed scripts. 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. patch-package, you can add them to this setup script.
:thought_balloon: You will need to make an effort to remember to run yarn setup instead of just yarn :lotus_position:
{
"scripts": {
"setup": "yarn install && yarn allow-scripts && ..."
}
}Experimental protection against bin script confusion
Bin script confusion is a new attack where a dependency gets its script to run by declaring executables that end up on the path and later get triggered either by the user or by other programs. More details in npm bin script confusion: Abusing ‘bin’ to hijack ‘node’ command by Socket.dev
To enable protection against bin script confusion, run all of the above allow-scripts commands with the --experimental-bins flag.
What does it do?
setupwill add a new configuration option to your project package manager RC file to disable linking up bin scriptsautowill generate an allowlist of top-level bin scripts allowed for executionrunwill link up the allowed scripts and replace not allowed scripts with an error
When you attempt to run a bin script not in the allowlist, you will get an error with instructions on how to enable it manually.
