Blog

Overview

Node.js is a popular back-end JavaScript runtime environment built on the V8 engine.

As part of our internal security research, we discovered numerous products in production environments installed with insecure permissions. One of these products was Node.js, and we decided to investigate further.

Node.js is vulnerable to local privilege escalation attacks (LPEs) under certain conditions on Windows platforms. More specifically, improper configuration of permissions in the installation directory allows an attacker to perform two different escalation attacks: %PATH% and DLL hijacking.  

For more information on this vulnerability class, see our previous blog post on the topic, as well as some similar vulnerabilities we have published to date (CVE-2021-29221CVE-2021-26556).

Exploitation

To demonstrate this flaw, we first downloaded the latest version of Node.js from https://nodejs.org/en/download/. During our research, we tested using Node.js version 14.17.0.

We followed the standard installation steps, except for the installation directory, which we changed to C:\tools using the installer GUI, as shown below:

We also select the option to “automatically install the necessary tools”.

After installation we then reviewed the permissions on the installation folder.  In the screenshot below, note the improper permissions, BUILTIN\Users Allow *, on C:\tools, which are inherited from the drive root. This gives any local user the ability to create arbitrary files in the installation directory.

This unprotected directory has also been added to the system %PATH% variable, allowing an attacker to drop malicious executables in that directory and have them executed by other users in certain circumstances. (Note that you may have to start a new PowerShell instance to see the %PATH% change.)

To fully demonstrate the implications of this vulnerability, first create a new unprivileged user. Then, as this user, drop a malicious exe into the C:\tools directory and rename it to npm.exe. For testing purposes, you can simply do cp node.exe npm.exe. Note that the same could be done for npx.

Windows will search for a program with the .exe extension first, meaning that the malicious npm.exe will take precedence over npm.cmd.

Now, as the privileged user, try running npm. This should drop you into the Node.js shell, demonstrating how an attacker could run a malicious executable.

A writable %PATH% directory would also allow an attacker to hijack the execution of any commands that come later in the path. From the default Node.js installation, this would include chocolatey, a software management tool for Windows. However, such a vulnerability would affect programs installed in the future as well.

Aside from the %PATH% vulnerability, the insecure permissions configured could also allow an attacker to perform a DLL hijacking attack against the node.exe. Using Process Monitor, we can confirm that node attempts to load a number of DLLs from the unprotected folder.

Adding malicious versions of these DLLs would also allow for arbitrary code execution as the user running such a service.

Timeline

May 27, 2021Reported to https://hackerone.com/nodejs
June 5, 2021Vulnerability triaged
June 11, 2021Node.js provided a proposed fix for review
June 12, 2021DeepSurface shared feedback on the proposed fix
July 1, 2021Node.js released versions v12.22.2, v14.17.2, and v16.4.1 containing the fix
July 6, 2021DeepSurface Security advisory released

The Fix

Node.js users on Windows should upgrade to versions v12.22.2, v14.17.2, or v16.4.1, according to the major version currently in use.  In addition, review the permissions of the installation directory to ensure only privileged users are able to add or modify files.  This is particularly important if Node.js is installed in a non-default location (e.g. outside of C:\Program Files\).  For more information, see our previous post discussing these very common permissions issues.

Acknowledgements

We would like to thank the Node.js security team for their excellent response and thoroughness in investigating this issue.