NPM is used as a convenient cross-platform package manager for a lot of developer tools. For many tools, the defacto way to install is npm install -g $TOOL
. But installing anything via npm allows it to run untrusted code on your machine.
Here are a few tips to minimize the risk:
1. NEVER run npm as sudo/root
Node's official documentation recommends not installing global packages as sudo/root. If you have already installed node through nvm
ignore this step. If you use a system installed node
e.g using Ubuntu's apt-get, read through this guide for Linux/Mac or npm-g-nosudo which is a shell script for Linux.
If you are lazy (like me), here's a summary from the linked guide:
mkdir -p "${HOME}/.npm-packages" && npm config set prefix "${HOME}/.npm-packages"
Add this to your .bashrc
or .zshrc
:
NPM_PACKAGES="${HOME}/.npm-packages"
export PATH="$PATH:$NPM_PACKAGES/bin"
# Preserve MANPATH if you already defined it somewhere in your config.
# Otherwise, fall back to `manpath` so we can inherit from `/etc/manpath`.
export MANPATH="${MANPATH-$(manpath)}:$NPM_PACKAGES/share/man"
2. Install/Use node using nvm
Node's official documentation recommends installing node as an unprivileged user using a node version manager.
Here are the steps:
- Install nvm. This does not work for Windows, use nvm-windows which is a totally different project from nvm.
- Unfortunately,
nvm
suffers from the curl pipe to bash install as its main way to install. - If you have git installed on your machine, you can also directly clone it using the following steps:
cd "$HOME" && git clone https://github.com/nvm-sh/nvm.git .nvm
cd "$HOME/.nvm" && git checkout v0.35.3 && . nvm.sh
- Add to your .bashrc or .zshrc:
- Unfortunately,
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
-
nvm install --lts
or whichever version of node you need. nvm use node
- To use a node version by default,
echo "lts/*" > "$HOME/.nvmrc"
3. List all your globally installed npm packages and remove any unnecessary ones
Listing global packages is done with npm ls -g --depth 0
Remove any unnecessary packages with npm uninstall -g $TOOL
You can check your shell history/scripts folders to see if you actually use many of the global packages.
4. Audit your packages
Run npm audit
in your project regularly to see if any dependencies are vulnerable. This only works for your development projects, not global packages.
A (hacky) way to npm audit
global packages:
- Run
npm
. The last line will show the folder of the global npm packages e.g$HOME/.npm-packages/lib/node_modules/npm
- Go to
$HOME/.npm-packages/lib
and runnpm init -y
and then runnpm i --package-lock-only
. These steps are required asnpm audit
checks forpackage.json
andpackage-lock.json
- Now run
npm audit
. Remove any dependencies which have high or too many moderate vulnerabilities. These could either be malicious or unmaintained tools. - Remove the
package.json
andpackage-lock.json
after the audit
5. Use npx
to run executables
Many times, it is not necessary to have a tool installed globally e.g create-react-app
. Node 6+ comes with npx
which allows you to temporarily download and run scripts. The benefits of using npx
over npm install -g
are beautifully explained in this post.
A gist of the article:
Calling npx when isn’t already in your $PATH will automatically install a package with that name from the npm registry for you, and invoke it. When it’s done, the installed package won’t be anywhere in your globals, so you won’t have to worry about pollution in the long-term.
This feature is ideal for things like generators, too. Tools like yeoman or create-react-app only ever get called once in a blue moon. By the time you run them again, they’ll already be far out of date, so you end up having to run an install every time you want to use them anyway.
Bonus : Use Deno for developer tools
I think a project like deno with good sandbox capabilities and limited permisisons is the best choice for a lot of developer tools currently made using Node. Read this post for more details on why everyone is talking about Deno.
Conclusion
Does this solve all security issues of node
/npm
on your machine? No! There are a lot of ways in which a malicious attacker can compromise your machine/project. This only prevents a bad npm tool from getting root access and removes globally installed npm tools with known insecure dependencies.
Top comments (0)