The Node.js Package Manager (or just npm)
allows the author of a malicious package to infect other packages and
propagate malicious scripts across the npm ecosystem and in the builds
of legitimate projects.
npm is to Node.js what apt-get is
for Linux and what gem is to Ruby. It's a simple method of retrieving
packages onto a PC/server, and then using them inside coding projects.
It's convenient, it's fast, it's well-designed, and that's why most
JavaScript developers love it these days.
But according to Google software engineer Sam
Saccone, design flaws in npm would allow a skilled attacker to cause
chaos in the entire JavaScript ecosystem.
Three (+ one) issues are the cause of npm's "vulnerability"
Before explaining what Mr. Saccone found, we also
must mention that when an "npm install" command is executed, besides
downloading and installing the desired package into your project, npm
allows the newly downloaded package to load and run adjacent scripts
(called lifecycle scripts).
These scripts are executed with the user's current
privileges, which on some operating systems may be root/system. This is a
known issue, but something that Mr. Saccone wanted to raise a concern
about, since other package managers also allow them.
What Mr. Saccone discovered is an exploit, which he
described in this write-up (embedded below), that leverages three npm
features.
The first revolves around the fact that npm uses the
SemVer versioning system. SemVer is not the problem here, but the fact
that these dependencies aren't locked to a specific version. Some
developers load dependencies with version number ranges, and even if a
developer locks down his code with fixed versions, some of the
dependencies he loads have other dependencies of their own, which may
use version number ranges.
The second problem relates around users that have an
npm author account, meaning they can publish packages to the npm
registry. npm doesn't have an automatic logout mechanism, so someone
that logged into the npm system, remains logged in up until he decides
to log out.
The third issue is the registry itself. npm is a
centralized registry. Code published via npm doesn't go through a review
process, and is available to anyone, almost instantly as someone has
hit Enter and the script was uploaded online.
One rogue npm package could propagate across the whole registry
With all these issues, Mr. Saccone has described a
very simple attack, which is a simple worm virus. It all starts with a
rogue npm pacakge, that besides legitimate features to entice other
developers to use it, also includes malicious code.
When another developer finds this malicious package,
and he deems the legitimate code to be useful in a project he may be
working on, he will include it in his project via an "npm install"
command.
When this malicious package is downloaded and
installed, those lifecycle scripts we mentioned earlier can execute
malicious behavior on the infected machine using the user's full
privileges.
Are you really installing Express?
If the developer that installed the malicious
package is also an npm author, he'll probably still be logged in, so the
malicious lifecycle script could very easily search the victim's
repositories, add its malicious code to their content, and then publish a
new version (patch level - 0.0.x). Additionally, the malicious
lifecycle script could also add the original malicious package as a
dependency to the victim's repos.
Since the updated modules are only at a bugfix
level, other repositories that rely on the infected victim's repos, if
they haven't locked down version numbers and use SemVer ranges, they'll
automatically load the malicious updates inside their projects.
Using this simple scenario, which Mr. Saccone dubbed as npm hydra worm, one attacker can wreck havoc on the entire npm registry in a matter of days.
npm doesn't have the resources to scan and review everyone's packages
Mr. Saccone disclosed the issue to npm at the start
of January, but the company said they don't have the resources to scan
all code uploaded to their registry and that they'll have to rely on the
community to detect such packages when they are detected.
"Ultimately, if a large number of users make a
concerted effort to publish malicious packages to npm, malicious
packages will be available on npm. npm is largely a community of
benevolent, helpful people, and so the overwhelming majority of software
in the registry is safe and often useful," the company
wrote on its blog yesterday.
"We hope the npm community continues to help us to
keep things that way, and we will do our best to continuously improve
the reliability and security of the registry," npm also added.
Currently, as it stands, npm won't take any steps to
fix this issue, since it thinks the repository's good parts far
outweigh the dangers of this exploit scenario. The company is also
recommending that developers install packages by limiting lifecycle
scripts, or disabling them altogether, see code below:
### Install package without running scripts
npm install [pkgname] --ignore-scripts
### Disable scripts execution globally
npm config set ignore-scripts true
Furthermore, npm leadership is also currently
exploring the scenario of using 2FA (two-factor authentication) for any
npm publish operations, as a way to prevent such worms from spreading.
Recent left-pad debacle has already pointed out weaknesses in npm
The issue has been taken seriously enough that US-CERT (United States Computer Emergency Readiness Team) issues yesterday a
public alert about this attack scenario.
In the past years, Node.js, as a technology, has
spread to an immense number of companies in the US and worldwide, which
may be affected if their local code repos are compromised.
Coincidentally, just three days ago, the recent
left-pad debacle
has proved the dangers of rogue packages as well. When a copyright
dispute angered developer Azer Koçulu enough to delete his entire repos,
a malicious actor could have easily taken over his liberated namespaces
and use them to publish malicious packages to other packages.
While nothing happened, this showed that npm is far
from perfect and that developers and npm should start thinking more
about security as the service grows in popularity. If we've learned
something from malware authors is that they'll go wherever the users
are, and more and more companies these days are using Node.js, so
prepare to see more npm or Node.js-based attack vectors.
Comments
Post a Comment