HTTP Multipart and Security Implications

Overview

HTTP multipart, specifically multipart/form-data, is a media type that allows the encoding of information as a series of parts in a single message. This was introcuded way back in 1998 as RFC 2388It is commonly used for forms that are expressed in HTML and where the form values are sent via HTTP. However, it can also be used for forms that are presented using representations other than HTML (like spreadsheets, Portable Document Format, etc), and for transport using other means than HTTP.

In breif, this is how it works:

  • 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 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.
  • Each part has an optional Content-Type, which defaults to text/plain. If the contents of a file are returned via filling out a form, then the file input is identified as the appropriate media type, if known, or application/octet-stream.
  • If multiple files are to be returned as the result of a single form entry, they should be represented as a multipart/mixed part embedded within the multipart/form-data.
  • Each part may be encoded and the content-transfer-encoding header supplied if the value of that part does not conform to the default encoding.

Below is an example of an HTTP Multipart Request and Response sequence. In this example, the Content-Type header specifies that the body of the request is multipart/form-data and provides a boundary string that is used to separate the different parts of the message. The body of the request contains two parts: one named "text" with the value "Hello World", and one named "file" with the filename "example.txt" and the content "This is the content of the file example.txt.".

POST /upload HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 343

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="text"

Hello World
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain

This is the content of the file example.txt.
------WebKitFormBoundary7MA4YWxkTrZu0gW--

Here's an example of a possible HTTP response to this request:

HTTP/1.1 200 OK
Date: Tue, 14 Jun 2023 12:00:00 GMT
Content-Type: application/json
Content-Length: 30

{
  "status": "upload successful"
}

In this example, the server responds with a status code of 200 (OK) and a JSON body indicating that the upload was successful. The Content-Type header in the response specifies that the body of the response is JSON. 

In relation to multipart, MIME types are used to specify the data type of each part in a multipart/form-data message. Each part in a multipart message can have a different MIME type. For example, one part could be plain text (text/plain), while another part could be a JPEG image (image/jpeg). This allows a single HTTP request to contain different types of data.

When sending large binary data or files, using multipart can be more efficient than other methods. This is because the data doesn't need to be encoded and decoded as it would if you were using a method like JSON. Multipart is a well-established standard and is supported by virtually all modern web browsers and web servers.

Security Implications

As with any data input, multipart data can be a vector for attacks if not handled properly. For instance, an attacker might attempt to exploit the system by sending maliciously crafted multipart data. This could include things like sending overly large files, or files that contain malicious code. Therefore, it's important to validate and sanitize all incoming data, limit the size of incoming files, and handle all data in a secure manner to prevent potential security issues.

Here's an example of a maliciously crafted HTTP multipart request. In this case, the attacker is attempting to perform a Path Traversal attack by providing a filename that includes directory traversal sequences.

 
POST /upload HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 343

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="../../etc/passwd"
Content-Type: text/plain

Malicious content here.
------WebKitFormBoundary7MA4YWxkTrZu0gW--

In this example, the attacker is trying to overwrite the /etc/passwd file, which is a critical system file on Unix-like operating systems.

To mitigate such an attack, you can use an F5 iRule to inspect the filename in the Content-Disposition header of each part in a multipart request and reject the request if the filename contains a directory traversal sequence. Here's an example of what that iRule might look like:

when HTTP_REQUEST {
    if { [HTTP::header exists "Content-Type"] } {
        set content_type [HTTP::header "Content-Type"]
        if { [string tolower $content_type] starts_with "multipart/form-data" } {
            HTTP::collect
        }
    }
}

when HTTP_REQUEST_DATA {
    set data [HTTP::payload]
    if { $data contains "filename=\"../" } {
        HTTP::respond 400 content "Invalid filename"
    } else {
        HTTP::release
    }
}

This iRule works by collecting the body of the request if the Content-Type header indicates that it is a multipart request. When the body of the request is available, it checks if the body contains the string filename="../. If it does, it responds with a 400 Bad Request error. Otherwise, it allows the request to proceed.

File Upload Security

Modern web application are expected to provide end users the ability to upload files. Sending files over HTTP Multipart poses a big security risk and without proper mitigations in place it can lead to a server compromise or a data breach. Developers, usually, can implement a number of checks  and validations to ensure no malicious file is uploaded the server.  These include blacklisting types of files that have dangerous extensions, validating the MIME-type of an uploaded file, checking image header, restricting execution of scripts in an upload directory using .htaccess, and in some cases doing validation of the file on the client side. Keep in mind though, some of these mitigations can be bypassed by a skillful attacker since they control the headers on an HTTP Request.

It is a good idea to combine application side mitigations with a WAF as part of layered defense strategy. F5 Advanced WAF offers a number of built in protections of multipart data as part of HTTP Protocol Compliance and ability to tightly control the file uploads.

BIG-IP ASM HTTP protocol compliance

 https://my.f5.com/manage/s/article/K10280

Bad multipart/form-data request parsing When the content type of a request header contains the Multipart/form-data substring, the system checks whether each multipart request chunk contains a Content-Disposition header containing a name value and corresponding parameter key value. For example: name="parameter_key". If the Content-Disposition header does not contain the required parameters, a violation is issued.

Note: Content-Disposition is not covered under HTTP Standard RFC 2616, but is instead covered separately under RFC 2183 - Communicating Presentation Information in Internet Messages: The Content-Disposition Header Field.

Bad multipart parameters parsing The system examines the requests to verify that the Content-Disposition header matches the format: name="param_key";\r\n.

The system also checks that the following is true:

* A boundary follows immediately after the request headers.
* The parameter value matches the format: ‘name="param_key";\r\n.
* A chunked body contains at least one CRLF.
* A chunked body ends with CRLF.

If one of these is false, a violation is issued.

ASM File Upload Specific Mitigtions

Published Jun 16, 2023
Version 1.0

Was this article helpful?

No CommentsBe the first to comment