logo

Database

Asymmetric denial of service - Content length

Need

Validation and enforcement of Content-Length field in requests

Context

• Usage of C# 7.1 for developing applications with advanced language features and improvements

• Usage of Microsoft.AspNetCore.Mvc for building web applications with ASP.NET Core MVC

Description

1. Non compliant code

[HttpPost]
public async Task<IActionResult> Post([FromBody] string data)
{
    // Process the data
    return Ok();
}

In the above code, the HTTP POST method accepts any amount of data from the client without any restrictions. The `[FromBody]` attribute tells the framework to get the data from the body of the HTTP request. When a client sends a request to this endpoint with a very large `Content-Length` header, the server will start reading the data and continue to do so until it has read the amount of data specified in the `Content-Length` header. While the server is waiting for the data to arrive, it keeps the connection open. This can be exploited by an attacker who sends a large `Content-Length` header, but only a small amount of data. The server will keep the connection open, waiting for the rest of the data to arrive, which it never does. This can lead to a Denial of Service (DoS) attack, as it can consume server resources and potentially block other legitimate requests.

2. Steps

• Implement input validation to ensure that the Content-Length field is within an acceptable range.

• Set a maximum limit for the Content-Length field to prevent excessively large values.

• Implement rate limiting or request throttling mechanisms to prevent an attacker from sending a large number of requests with high Content-Length values.

• Implement timeout mechanisms to terminate idle connections after a certain period of inactivity.

• Consider implementing request size limits to prevent excessively large requests from consuming server resources.

• Regularly update and patch the server software to ensure that any known vulnerabilities related to Content-Length handling are addressed.

3. Secure code example

[HttpPost]
[RequestSizeLimit(1000000)] // Limit the request size to 1MB
public async Task<IActionResult> Post()
{
    long? contentLength = HttpContext.Request.ContentLength;
    if (contentLength > 1000000) // Check if the Content-Length is more than 1MB
    {
    }...

The updated code includes several measures to mitigate the risk of an asymmetric denial of service attack via the Content-Length field. Firstly, the `[RequestSizeLimit(1000000)]` attribute is added to the `Post` method. This attribute sets a maximum limit for the size of the request body to 1MB. This prevents an attacker from sending a request with an excessively large body. Next, the `Content-Length` of the request is retrieved and checked. If the `Content-Length` is more than 1MB, the method returns a `BadRequest` response. This is an example of input validation, which ensures that the `Content-Length` field is within an acceptable range. The `StreamReader` is used to read the request body. This is done within a `using` statement to ensure that the `StreamReader` is properly disposed of after use, which helps to prevent resource leaks. Finally, the method returns an `Ok` response if the request is processed successfully. In addition to these code changes, it's also recommended to implement rate limiting or request throttling mechanisms to prevent an attacker from sending a large number of requests with high `Content-Length` values. Timeout mechanisms should also be implemented to terminate idle connections after a certain period of inactivity. Regularly updating and patching the server software is also important to ensure that any known vulnerabilities related to `Content-Length` handling are addressed.