Chapter 9. Using Components with Known Vulnerabilities

This Open Web Application Security Project (OWASP) Top 10 risk highlights the threats from using external dependencies in an application. For Node applications, these dependencies range from Node.js binary itself to frameworks such as Express and thousands of modules available on npm. Security vulnerabilities in these dependencies directly affect the application. As a result, it is a critical task for Node developers to stay aware of any vulnerabilities discovered in an application’s external dependencies and diligently keep the application safe against it.

Attack Mechanics

Let’s review how attackers can exploit these vulnerabilities.

Exploit Publicly Known Vulnerabilities

As a first step of an attack, malicious actors typically perform application foot-printing to discover the platform, frameworks, and server on which the application is built. When this is known, an attacker can look up publicly known common vulnerabilities and exposures (CVEs) published for that platform and apply them toward the target application. In other cases, attackers automate exploits based on CVEs and spray them across the internet to catch the prey.

Exploiting publicly known vulnerabilities often yields success for attackers. As per a research study done by Verizon, 99 percent of close to 80,000 security incidents in the year 2014 involved exploiting vulnerabilities for which CVEs were published at least a year earlier, some published as far back as 1999. Thus, even decade-old CVEs often prove useful to attackers and are actively exploited in the wild.

For Node apps, the applicable CVEs include Node.js vulnerabilities, as well as advisories found in Node modules.

Publishing Malicious Modules to npm

The npm code of conduct has an explicit policy against malware, stating that “a package which is designed to maliciously exploit or damage computer systems is not allowed.” However, in the spirit of being an open and community-driven environment, npm doesn’t impose a formal audit or an approval process before a module can be published.

Although the following are not very common, here are some possible ways by which an attacker could sneak in a malicious module on victim user’s application:

  • By publishing a module that provides some useful features, but performs malicious activities under the hood.

  • By naming a malicious module with a spelling that is very close to an existing popular module, targeting npm users who fat-finger and mistype the actual module name.

  • By compromising popular module author’s npm account (by using brute-force attack, or exploiting HTTP Bearer Token Vulnerability in npm <v2.15.1 or <v3.8.3, for example), and publishing a new version of a module with malicious code.

To implement a malicious package, an attacker could take advantage of the npm-script hooks in the package.json that allow executing a script or command on the server. As an alternate option, an attacker could have the module send files or data to an external location, delete files, or install additional malicious files by using Node core APIs such as filesystem, child process, and HTTP. The possibilities of what an attacker could do after the malicious package is installed are limited only by permissions of the user the application is running as.

Exploit Unpublished Zero-Day Vulnerabilities

This mechanism involves an attacker using unpublished vulnerabilities in Node.js or Node modules for which no patch or release with fixes exists.

Protecting Against Unsecured External Components

Because it is unlikely that you can avoid external dependencies of a Node application, let’s go over some ways to protect against related threats.

Vet npm Modules Before Using Them

As vulnerabilities in any npm module that an application uses directly affect the security of the application, you need to be diligent in reviewing the module for potential security issues before installing and using it.

As a heuristic approach, you should prefer using a module that is written by a reputable author, actively maintained by the community, has a healthy amount of download stats, and comes with an extensive test suite.

If these general guidelines fail to establish a good confidence level, but you have good reasons to use a module, you should undertake to review the source code of the module. The following are a few ideas about what to look for during the code review.

Scripts in package.json

Before installing a module, check the scripts section in the package.json, either from the source code or by running the npm view <pkgname> scripts command.

Ensure that hooks such as preinstall, install, postinstall, preuninstall, uninstall, or postuninstall do not invoke any unexpected command or script. Verify that no commands have a “sudo” prefix.

Usage of Node core APIs

Inside the module code under review, check whether Node core APIs and bindings are being used that could potentially help an attacker conducting malicious activities such as deleting, updating, or adding files, sending data over the network to a remote location, executing commands on the server, and so on. The commonly used core modules for such activities are fs, dns, http, https, net, os, child_process, and zlib. If you notice these modules being used in the source code, verify its necessity for the module’s intended functionality and the way it is used.

Blacklisting Node.js Core Modules and Bindings by Using N|Solid

N|Solid is a Node.js runtime that has been enhanced to address the needs of the enterprise. It provides a way to blacklist Node core modules and bindings that could be harmful. It allows specifying severity levels to ignore, warn, throw an error, or exit an application when a function on a blacklisted core module or binding is used by the application code or external modules, thus helping to detect possibly harmful code.

There is an excellent article with more details on blacklisting.

Keep Versions of Node.js, and npm Modules Up to Date

Keep watch on vulnerabilities found and patched in Node.js runtime and npm modules that your project uses. Here are some useful tools and resources to keep track of these security updates:

Node.js

npm modules

Maintaining a Test Suite

You can incorporate most of these tools in the build script and run them as part of the continuous integration.

In addition, maintaining a good test suite for application code is extremely useful to ensure functionalities work as intended after upgrading the dependencies.

Apply the Principle of Least Privilege

The privileges of a user that an application is running under are important in limiting the extent of the damage an unsecured external dependency could cause. Therefore, limit these access privileges to an absolute minimum.

Conclusion

The majority of code in a Node application comprises external dependencies. Because this is inevitable, the security of the application is only as strong as the weakest link in its dependencies.

In this chapter, we covered strategies to vet such external dependencies, along with tools and resources useful to stay on top of ever-emerging vulnerabilities and security updates for these dependencies.

Additional Resources

Here are some additional articles and resources on this topic:

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset