Question

Limiting the size of a RequestBody

I have following controller. Which takes a post request and process as required.

@RestController
@RequestMapping("/login")
public class LoginController {

    @RequestMapping(method = RequestMethod.POST)
    public String login(@RequestBody LoginRequest loginRequest) {
        
        if (loginRequest.getUsername().length() < 5 || loginRequest.getUsername().length() > 10) {
            return "Username must be between 5 to 10 character.";
        }
        ...
        return "This is the login response.";
    }

}

LoginRequest.java

public class LoginRequest {
    private String username;
    private String password;

    public LoginRequest() {
    }

    public LoginRequest(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getUsername() {
        return this.username;
    }
    ...
}

As seen above, the parameter are passed as HTTP request body @RequestBody LoginRequest loginRequest

The issue is currently, someone can send malicious requests with random large amount of data. For e.g. a username of 5000 characters. Though the authentication would fail but still multiple such request can impact the performance of the server, and makes it vulnerable to DoS attacks.

Hence, I want to enforce a size validation on application level over the incoming request body. E.g. it shouldn’t be more than 10mb etc. However, I am not sure, how to do it.

A similar question is here, however i am not using jboss and also changing server configurations isnt an option and looking to limit or resolve it on application level. Also, my request isnt a form multipart but rather JSON sent as request body.

 3  67  3
1 Jan 1970

Solution

 1

As you mentioned, limiting the request size is an effective strategy to prevent resource exhaustion caused by large requests. This can be achieved by validating the overall request size rather than individual field sizes. Here's an example implementation using the '@MaxByteLength' annotation:

@RestController
@RequestMapping("/login")
public class LoginController {

    @MaxByteLength(value = 1024 * 1024 * 10) // 10 MB Limit (adjust as needed)
    @RequestMapping(method = RequestMethod.POST)
    public String login(@RequestBody LoginRequest loginRequest) {

        // Your code here...

    }
}

The @MaxByteLength annotation conveniently handles request size validation. It's a clean, simple, and efficient approach.

To import this annotation, use either:

From JAVAX:

import javax.validation.constraints.MaxByteLength;

From JAKARTA:

import jakarta.validation.constraints.MaxByteLength;

I hope this helps!

From Brazil.

2024-07-13
Kayky

Solution

 0

Your question as it's phrased might provide you with answers that probably won't fix your issue as it seems to be security related.

Let's see the following part of your question

The issue is currently, someone can send malicious requests with random large amount of data. For e.g. a username of 5000 characters. Though the authentication would fail but still multiple such request can impact the performance of the server, and makes it vulnerable to DoS attacks. Hence, I want to enforce a size validation on application level over the incoming request body

Since your question is related with spring boot, in spring boot we have 1 server (e.g. Tomcat) deployed that hosts 1 application. If you make such validation on application level and inside your code as you suggest, this would mean that the server hosting your application would have already accepted the message and would already be prone to Dos attacks. So there is no reason (at least as described in question) for you to make such implementation in your application code.

The default server if not defined otherwise for spring-boot is tomcat. Tomcat already has thought about Dos attacks and has several mechanisms in place for such actions, such as maxPostSize & maxSwallowSize configurations in connector.

According to the doc this can also be configured with a property in your application.yaml for spring-boot to transfer those configurations to tomcat when deployed.

server.tomcat.max-swallow-size , Maximum amount of request body to swallow, default: 2MB

server.tomcat.max-http-form-post-size Maximum size of the form content in any HTTP post request, default: 2MB

Jetty and Undertow which are alternatives of tomcat if configured as servers in spring-boot also provide a similar set of properties for the same reason.

2024-07-14
Panagiotis Bougioukos