Malicious packages in npm. Here’s what to do

Here’s all the information I’ve found.

?☠️?

What happened?#

People found malicious packages in npm that work like real ones, are named similarly real ones, but collect and send your process environment to a third-party server when you install them:

This is dangerous because, on CI servers, the environment usually includes different secret tokens.

What to do if I’m a user?#

Regenerate the secret tokens if you installed any package from these as a dependency:

A screenshot of the cached page with packages

npm has also confirmed this list

babelcli - v1.0.1 - Babel CLI for Nodejs
crossenv - v6.1.1 - Run scripts that set and use environment variables across platforms
cross-env.js - v5.0.1
d3.js - v1.0.1 - d3.js for Nodejs
fabric-js - v1.7.18 - Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.
ffmepg - v0.0.1 - FFmpeg for Nodejs
gruntcli - v1.0.1 - Grunt CLI for Nodejs
http-proxy.js - v0.11.3 - Node.js proxy tools
jquery.js - v3.2.2-pre - jquery.js for Nodejs
mariadb - v2.13.0 - A node.js driver for mysql. It is written in JavaScript, does not require compiling, and is 100% MIT licensed.
mongose - v4.11.3 - Mongoose MongoDB ODM
mssql.js - v4.0.5 - Microsoft SQL Server client for Node.js.
mssql-node - v4.0.5 - Microsoft SQL Server client for Node.js.
mysqljs - v2.13.0 - A node.js driver for mysql. It is written in JavaScript, does not require compiling, and is 100% MIT licensed.
nodecaffe - v0.0.1 - caffe for Nodejs
nodefabric - v1.7.18 - Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.
node-fabric - v1.7.18 - Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.
nodeffmpeg - v0.0.1 - FFmpeg for Nodejs
nodemailer-js - v4.0.1 - Easy as cake e-mail sending from your Node.js applications
nodemailer.js - v4.0.1 - Easy as cake e-mail sending from your Node.js applications
nodemssql - v4.0.5 - Microsoft SQL Server client for Node.js.
node-opencv - v1.0.1 - OpenCV for Nodejs
node-opensl - v1.0.1 - OpenSSL for Nodejs
node-openssl - v1.0.1 - OpenSSL for Nodejs
noderequest - v2.81.0 - Simplified HTTP request client.
nodesass - v4.5.3 - Wrapper around libsass
nodesqlite - v2.8.1 - SQLite client for Node.js applications with SQL-based migrations API
node-sqlite - v2.8.1 - SQLite client for Node.js applications with SQL-based migrations API
node-tkinter - v1.0.1 - Tkinter for Nodejs
opencv.js - v1.0.1 - OpenCV for Nodejs
openssl.js - v1.0.1 - OpenSSL for Nodejs
proxy.js - v0.11.3 - Node.js proxy tools
shadowsock - v2.0.1 - A tunnel proxy that help you get through firewalls
smb - v1.5.1 - A Pure JavaScript SMB Server Implementation
sqlite.js - v2.8.1 - SQLite client for Node.js applications with SQL-based migrations API
sqliter - v2.8.1 - SQLite client for Node.js applications with SQL-based migrations API
sqlserver - v4.0.5 - Microsoft SQL Server client for Node.js.
tkinter - v1.0.1 - Tkinter for Nodejs

Here’s also a one-liner that will list these packages if any of them was installed as a dependency:

Twilio also listed one-liners for checking the whole file system at once (for bash and Powershell)
npm ls | grep -E "babelcli|crossenv|cross-env.js|d3.js|fabric-js|ffmepg|gruntcli|http-proxy.js|jquery.js|mariadb|mongose|mssql.js|mssql-node|mysqljs|nodecaffe|nodefabric|node-fabric|nodeffmpeg|nodemailer-js|nodemailer.js|nodemssql|node-opencv|node-opensl|node-openssl|noderequest|nodesass|nodesqlite|node-sqlite|node-tkinter|opencv.js|openssl.js|proxy.js|shadowsock|smb|sqlite.js|sqliter|sqlserver|tkinter"

Always check the name of packages you’re installing. You can look at the downloads number: if a package is popular but the downloads number is low, something is wrong.

What to do if I’m a library developer?#

I see two options:

  • Use scopes (@scope/package-name) for your packages. With scopes, it’s harder to install a wrong package accidentally: a user would have to misspell both the scope name and the package name. Unfortunately, it’s not: it’s enough to misspell just the scope name (e.g @babel/babel-cli@bable/babel-cli). Scopes might help a bit because they can have a simple name that’s harder to misspell, but it’s still not a universal solution.
  • Take the most common misspellings of your packages by yourself. Think of the most common misspellings and publish empty packages under these names. You can also warn users about the right name with npm deprecate.

Is this even OK?#

This isn’t surprising – npm doesn’t have any protection against this yet. In fact, that’s why there could be other malicious packages. Stay careful and check package names.

npm is working on a solution though:

You can also participate in the Yarn’s discussion about a white list for preinstall/postinstall script packages.


Author: Ivan Akulov

I'm a software engineer specializing in web performance, JavaScript, and React. I’m also a Google Developer Expert. I work at Framer.

4 thoughts on “Malicious packages in npm. Here’s what to do”

  1. Snyk.io provides a vulnerability database and service that can find and even fix issues in repos. A friend of mine built a proof-of-concept NPM proxy on top of Snyk (https://github.com/derekdorr/snyxy) that prevents known-bad packages from being downloaded. We had talked about using this in cooperation with a local NPM proxy/server to help protect an organization from vulnerable or malicious packages.

    NPM’s wide-open design is a double-edged sword. If your company has virus scanning on your email server, wouldn’t you also invest time into vetting executable code you install from the Internet?

  2. I’ve started working on a tool called npm-lint (https://github.com/tanepiper/npm-lint) that has a focus on being able to secure a package.json (such as trusted sources, or trusted apps for scripts for example). Eventually I’d like this to be checking all dependencies-of-dependencies and use things like Snyk (mentioned above) as a way to check for vulnerabilities. Adding a blacklist of modules could also be a feature I add to this. No one has really looked at this tool yet, but I’d be happy to work with ideas and suggestions that can help developers secure their local and production environments.

  3. Thanks for this article.
    Here’s the one-liner adaptation for those using Yarn:

    yarn list | grep -E "babelcli|crossenv|cross-env.js|d3.js|fabric-js|ffmepg|gruntcli|http-proxy.js|jquery.js|mariadb|mongose|mssql.js|mssql-node|mysqljs|nodecaffe|nodefabric|node-fabric|nodeffmpeg|nodemailer-js|nodemailer.js|nodemssql|node-opencv|node-opensl|node-openssl|noderequest|nodesass|nodesqlite|node-sqlite|node-tkinter|opencv.js|openssl.js|proxy.js|shadowsock|smb|sqlite.js|sqliter|sqlserver|tkinter"

Comments are closed.