== Summary ==
The Node package “aws-lambda-multipart-parser” was found to be vulnerable to a ReDoS (Regular-Expression Denial of Service) attack vector. This vulnerability enables a malicious user to cause each AWS Lambda function which uses it to stall until it times out. An attacker may send numerous concurrent malicious requests to an AWS Lambda function which uses this package, until the concurrent executions limit is reached, and in turn, deny other users access to the application. An attacker may also push the Lambda function to “over-execute” for long periods of time, essentially inflating the monthly bill and inflicting a financial loss for the target organization.
This vulnerability stems from both SAS-8 ('DoS & Financial Resource Exhaustion') as well as SAS-6 ('Insecure 3rd Party Dependency') in the Serverless Security Top 10 Most Common Weaknesses Guide.
== Technical Details ==
Overview of HTTP “Multipart/Form-Data” Requests
RFC 2388 defines a new “multipart/form-data” media type (Content-Type header value), as follows:
The media-type multipart/form-data follows the rules of all multipart MIME data streams as outlined in [RFC 2046]. In forms, there are a series of fields to be supplied by the user who fills out the form. Each field has a name. Within a given form, the names are unique. "multipart/form-data" contains a series of parts. Each part is expected to contain a content-disposition header [RFC 2183] where the disposition type is "form-data", and where the disposition contains an (additional) parameter of "name", where the value of that parameter is the original field name in the form. For example, a part might contain a header:
Content-Disposition: form-data; name="user"
with the value corresponding to the entry of the "user" field.
Below is an example of the structure of an HTTP POST request, which uses the “multipart/form-data” content type:
The “boundary” field, which serves as a boundary between the body parts, is defined in RFC 1341 ( https://tools.ietf.org/html/rfc1341 ).
A real HTTP multipart/form-data request, generated by the Chrome browser, is presented below, where the boundary field was defined by the client as the string:
The “aws-lambda-multipart-parser” Node Package:
The “aws-lambda-multipart-parser” Node package web page - https://www.npmjs.com/package/aws-lambda-multipart-parser , describes the package as follows:
“Support of multipart/form-data requests is a relatively new feature for AWS Lambdas. Although, there is such feature, majority of libraries for parsing multipart/form-data requests is based on server technology, which can't be used in case of AWS Lambdas. That's why, AWS Lambda specific multipart/form-data parser was created.”
As the description explains, the library is meant to provide AWS Lambda developers with a simple interface to the parsed multipart/form-data request body of incoming AWS API gateway requests.
Overview of ReDoS (Regular Expression Denial of Service):
A ReDoS attack is defined by Wikipedia as follows:
“The regular expression denial of service (ReDoS) is an algorithmic complexity attack that produces a denial-of-service by providing a regular expression that takes a very long time to evaluate. The attack exploits the fact that most regular expression implementations have exponential time worst case complexity: the time taken can grow exponentially in relation to input size. An attacker can thus cause a program to spend an unbounded amount of time processing by providing such a regular expression, either slowing down or becoming unresponsive”
Versions prior to 0.1.2 of the “aws-lambda-multipart-parser” Node package contain a ReDoS vulnerability, caused by the following code in the index.js file:
In line #8 - the boundary string sent by the client is extracted from the Content-Type header.
The developer of the package chose to turn the boundary string into a regular expression object by calling the RegExp() constructor and using it inside the body’s split() method.
Since both the boundary string, as well as the body of the request are under the full control of the client, a malicious user can craft a multipart/form-data request, in a way that will cause a ReDoS attack to occur.
An example of such a malicious request is presented below:
In this example, the boundary string was chosen to be the extremely inefficient regular expression (.+)+$.
This boundary string, with a simple request body as the one provided above, will cause a 100% CPU utilization for a very long period of time. In fact, on a MacBook Pro, with a 3.5Ghz Intel Core i7 CPU, the Node process did not finish parsing the body, even after 10 minutes(!) of running. When testing against an AWS Lambda function which uses this node package, the function always hit the maximum time out allowed by the platform.
An attacker may send numerous concurrent malicious requests to an AWS Lambda function which uses this package, until the concurrent executions limit is reached, and in turn, deny other users access to the application. An attacker may also push the Lambda function to “over-execute” for long periods of time, essentially inflating the monthly bill and inflicting a financial loss for the target organization.
== Remediation ==
The author of the node package, acknowledged and fixed the vulnerability within 48 hours of getting notified. The new version - v0.1.2 is no longer vulnerable.
== Serverless Security ==
Just like any other type of software, your serverless functions may be vulnerable to application layer attacks. If your functions contain vulnerabilities, malicious users and hackers will quickly find and exploit them in order to tamper or steal sensitive data, damage your application, deny service from other users and so forth. In order to withstand such attacks, your serverless functions require a solution for protecting them against application layer attacks.
This vulnerability stems from both SAS-6 ('Insecure 3rd Party Dependency') and SAS-8 ('DoS & Financial Resource Exhaustion') in the SERVERLESS SECURITY TOP 10 MOST COMMON WEAKNESSES GUIDE.
To learn more about serverless security, visit our website: https://www.puresec.io
== References ==
- This vulnerability is tracked under CVE-2018-7560
- aws-lambda-multipart-parser NPM page: https://www.npmjs.com/package/aws-lambda-multipart-parser
- OWASP ReDoS page: https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS