The npm community is no stranger to package controversy. As a repository collecting the world’s Node.js projects and making them available for free download to all developers, npm occasionally experiences a touch of drama coming from one of those thousands of hosted packages.
This week, a new controversy came about at the hands of a malicious developer intentionally poisoning and reposting an existing package.
Enter Crossenv, an identical package, with an identical description. The only difference was the missing dash, and the addition of some malware into the source code.
“Anyone who uses npm is automatically allowing usually-unreviewed arbitrary remote code execution. The npm libraries you install can themselves execute _any_ code. Even if you use –ignore-scripts, you’re still loading the code, or the code of some dependency. This is a known issue not just with npm but with literally any uncurated package manager ecosystem, which includes pretty much all the major language package managers (rubygems/bundler, pypi, cpan, bower, cocoapods, etc),” wrote Marchán in a blog post. “So that’s the baseline we actually have: by using a package manager you are expressing a certain level of trust in the entire system.”
She went on, “That said, npx can do certain things to mitigate the more glaring issues (things like typosquatting, which is *very* rare in the npm ecosystem based on actual research), but it’s also going to make sure it’s a reasonably useful tool. npm is already working on other mitigations that would improve the situation for both npm and npx (coming soon!), but ultimately, anyone who uses either tool is choosing to put themselves at some level of risk in exchange for convenience,” wrote Marchán.
CJ Silverio, chief technology officer at npm, said that the attacker was dealt with quickly and that the actual attack vector of typosquatting in the npm repository wasn’t a terrifically effective way to spread malware. For one thing, she said that the package couldn’t replace existing cross-env packages due to the naming difference. Even if someone accidentally added it to an existing project that used cross-env, that little name difference ensures that the code wouldn’t resolve properly at compile time, just as it wouldn’t if the developer had mistyped the package name in the code.
Indeed, the only developers who this could have affected would be those that were building a brand new project and included the mistyped crossenv package right from the start. This ensures that between the package being uploaded on July 19 and it being taken down on Aug. 1, only new projects were at risk.
Silverio also said that developers tend to Google a package before they use it, meaning that most users of cross-env would have found it by searching the web, not by simply typing words into an npm command. In total, there were likely fewer than 50 exposures to this package. Thus, she added, typosquatting is not a very effective way to spread malware.
“Package squatting has mostly been happening around competitive modules. We had someone who named their date parsing and handling library something similar to Moment.js causing deliberate confusion between the two. Usually, that’s been it. I haven’t seen malicious squatting, though I was aware it was possible. Usually, it’s accidental,” said Silverio.
That doesn’t mean Silverio and the npm team won’t be making changes to ensure this doesn’t happen again. One way they propose to find typosquatters is by diff‘ing project descriptions against each other. In this case, such a comparison would have caught crossenv.
The other solution, said Silverio, “Is to do some nearest neighbor checks on project names programmatically, but in the end, human review ends up being required even for that.” She said that the goal is to automate the process as much as possible. There are far too many packages in npm for them all to be hand reviewed for security issues, said Silverio.
Silverio also pointed out that security around the npm repository is provided by other companies, such as ^Lift Security. ^Lift offers its own Node Security Platform (NSP), which adds security checks into a GitHub-based workflow. Silverio said that ^Lift also does extensive package analysis against the npm registry.
Another security firm Silverio recommends is Snyk, a company which offers tools for finding security vulnerabilities in Node applications and their dependencies. Silverio said that these companies can offer the extra layer of Node package security and monitoring most enterprises require.
“What I recommend people do is hire ^Lift Security or work with Snyk, because these are the companies that have their whole business model around doing this specifically: analyzing packages, giving you advice about it, maintaining, and curating lists of things they’ve audited by hand… It requires specific expertise, which npm at the moment doesn’t have, which is why we work with them. We have them scan all the registry code to make sure we’re not making mistakes,” said Silverio.
“[^Lift] does interesting things with bulk registry data. When this arrived in our inbox, the first thing I did was send it to [^Lift]. Was this the only occurrence in the registry? We have enough data that he gave us some amount of confidence we cleaned this up,” said Silverio.
There was another source of luck that kept this problem from expanding beyond the confines of a few users as well. Silverio said that a lot of developers don’t even type in package names when building their projects from scratch, anymore. Instead, they often copy paste package dependencies from other projects, or from web pages explaining a project.
This copy-pasting helped to keep the spread of the malware low, as any typos were prevented from even surfacing. While some in the community would decry the prevalence of copying and pasting code, Silverio said that here, it actually saved the day.