Scan your projects for crossenv and other malicious npm packages

August 02, 2017
Written by

JDKpeyemdlB4gEQtUasRJc3TLJX2YMezcWfZ2spVkziJYzm6qHB1Gh8ppP31XiLeqfL60kz8DzePc3qYncMPAjqg_nAaXqr-zLETqo1lsrxy_SHjKnaQrg7UeNter8tyzft_Zz18

On August 1st, Oscar Bolmsten tweeted about how he found a malicious npm package called crossenv that scans for environment variables and POSTs them to a server.

This is particularly dangerous considering that you might have secret credentials for different services stored in your environment variables. Apparently it’s also not limited to just crossenv, but a series of packages — all of them are names of popular modules with small typos such as missing hyphens.

Check your project for malicious packages

These packages have been taken down by npm, but since credential theft happens upon installation, you should check if you have installed one of them. Ivan Akulov was so kind to compose and publish a list of (at least some of) these malicious packages on his blog. He also wrote a small one-liner that you can execute to check if these packages are installed in your current project:

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"

Search for infected projects on Mac/Linux

If you are like me a person who regularly develops Node.js applications you might have a series of projects and not just one project to check for. I extended Ivan’s command for that reason using find and xargs to actually scan all subdirectories of the folder that contains my projects and execute Ivan’s command there. You can run it by simply copy pasting this command into your command-line:

find . -type d -maxdepth 4 -name node_modules -print0 | xargs -0 -L1 sh -c 'cd "$0/.." && pwd && npm ls 2>/dev/null | 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"'

I know this is quite a long command so what does it do?

  1. It searches recursively from your current directory down into the subdirectories for folders that are named node_modules using the find command. The depth is currently limited to 4 but you might want to alter that depending on your project structure.
  2. It will then use xargs to parse and execute a command for every line (e.g. directory) that is returned by find
  3. The command that it will execute in a new shell instance performs a few things by itself:
  1. First the shell navigates into the parent directory of the node_modules folder
  2. It will print the current directory using pwd to show you which directory it’s currently scanning (no worries it doesn’t mean that that directory is infected)
  3. Afterwards it will run npm ls which lists all installed modules of that project
  4. Since npm ls might output some errors of missing dependencies or similar we will pass all messages to stderr to /dev/null (i.e. discard them)
  5. For everything else we will pipe the output through grep to check if it contains any of the malicious packages. If it finds one it will list it under the the respective path.

Search for infected projects on Windows

That command works when you are on Mac or Linux.. Corey Weathers wrote a small PowerShell script for that will do the same thing on Windows:

Get-ChildItem $directory -Directory -Recurse -Include "node_modules" | foreach { cd $_.FullName; cd ..; npm ls | Select-String -Pattern "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"} -ErrorAction Ignore

How do I see if it found a malicious package?

The output should be similar to this example (where I actually searched for express instead to demonstrate it).

screenshot-npm-vulnerability.png

What if a malicious package was detected?

You should immediately rotate all secrets that you have stored in the environment variables. If it’s a project that is shared with other folks don’t forget to alert them to do the same. Don’t forget that Continuous Integration systems and cloud hosts like to use environment variables as well. So if you shipped one of these projects into production or used a system that uses environment variables don’t forget to rotate them there as well.

It didn’t find any malicious packages so I’m good right?

Well this is just a list of packages that we know of but since the npm ecosystem is massive it’s hard to know if these were all. So if you want to be sure simply rotate the secrets nevertheless.

What if I found another malicious package?

If you found another malicious package make sure to report it to npm that it can be taken down as soon as possible. There is more information on how to contact them at on their website or simply shoot an email to security@npmjs.com.

Is there a way I can see if my Twilio account has been compromised?

If you discovered you used one of these libraries with an application using your Twilio Account Credentials you may want to check for unusual spike in product usage, such as phone calls or messages. Also make sure to change your secret or API Key/Secret depending on what you use.

In case you have any questions feel free to shoot me a message: