BOOK THIS SPACE FOR AD
ARTICLE ADA Node.js module downloaded millions of times has a security flaw that can enable attackers to perform a denial-of-service (DoS) attack on a server or get full-fledged remote shell access.
Assigned CVE-2020-7699, the vulnerability lies in the "express-fileupload" npm component, which has been downloaded at least 7.3 million times from npm.
The estimate is conservative as it does not take into account downloads from GitHub, mirror websites, and other cloned repositories.
This type of vulnerability, known as 'Prototype Pollution,' typically occur in JavaScript (JS) code due to the fundamental nature of the language. Because JS is a prototype-based language, every object, function, and data structure in the language has an inherent "Prototype" property that can be modified via the "_proto__" mutator.
The ability to modify existing code is an intended feature that allows for the easy extension of the existing objects, with more properties and methods.
Prototyping attacks such as this one leverage this 'design flaw' by injecting incompatible types of objects into existing ones to cause errors, leading to Denial of Service (DoS) at the very least, if not remote shell access..
Exploiting the Prototype
The actual attack is made possible because of the "parseNested" feature provided by express-fileupload. When enabled, the "parseNested" option is responsible for "flattening" the uploaded JSON data into nested objects.
Posix, the security researcher who discovered this flaw explains in a blog post, "The express-fileupload module provides several options for uploading and managing files in the [Node.js] application. Among them, the parseNested make argument flatten."
Therefore, if we provide {"a.b.c": true} as an input, internally, It will used as {"a": {"b": {"c": true}}}"
For example, if your application was using the "express-fileupload" module to facilitate file uploads, and the "parseNested" option set to "true," this would instruct the server-sided application to start flattening the received data into nested JSON objects.
This 'parseNested' option is illustrated in the image below.
Source: GitHub
When a simple payload is provided in the "Content-Disposition" HTTP header, an attacker can provide a "__proto__.toString" value to trigger the attack.
Source: GitHub
Recall, the "_proto__" mutator can influence JavaScript's "Prototype" property as inherited by all JS objects and structures.
Essentially, the HTTP request shown here will override and corrupt the build-in "toString" method of every object present in your code.
"If Object.prototype.toString can be polluted, this will cause an error, and for every request, express [sic] always returns 500 error," said the researcher.
Remote code execution via reverse shell
A more sophisticated variation of this exploit described by the researcher enables an attacker to get a shell on the vulnerable system. This exploit, however, largely depends on if the application using a vulnerable "express-fileupload" version, was also using the templating engine EJS (Embedded JavaScript templates).
Suppose your application was using EJS for parsing the uploaded data without additional checks in place. An attacker can then send an HTTP request that overwrites the "outputFunctionName" option of EJS.
(Source: Posix)
The payload shown above exploits prototype pollution within express-fileupload, and instructs EJS (should it be in use) to launch a Node.js "child_process." This newly launched process further spawns a reverse shell to the attacker's computer.
Once the connection is established, an attacker can now execute arbitrary code on the compromised server.
(Source: Posix)
Not all installations impacted
The researcher, however, told The Daily Swig blog that the flaw might not impact all users. Only those applications with "parseNested" option enabled are vulnerable to this prototype pollution flaw.
Moreover, to achieve full-fledged shell access and remote code execution, another library such as EJS, in conjunction with the vulnerable express-fileupload, is a prerequisite. It is worth noting though that EJS is not the only library that can make shell access possible.
Posix told The Daily Swig that the attacks didn't only impact EJS, “My post explains how to get a shell through EJS. [But] because the prototype pollution can change the flow of various contexts, simply adding a few referenced modules can create many possibilities for attackers.”
Within a few hours of receiving the researcher's report, the "express-fileupload" fixed the vulnerability, and users should consider getting the latest, patched version 1.1.9 from npm.