Lack of Resources and Rate Limiting

Severity: High
Test name: Lack of Resources and Rate Limiting
Summary

API requests consume resources such as network, CPU, memory, and storage. The amount of resources required to satisfy a request greatly depends on the user input and endpoint business logic. Also, considering the fact that requests from multiple API clients compete for resources. An API is vulnerable if at least one of the following limits is missing or set inappropriately (e.g., too low/high):

  • Execution timeouts
  • Max allocable memory
  • Number of file descriptors
  • Number of processes
  • Request payload size (e.g., uploads)
  • Number of requests per client/resource
  • Number of records per page to return in a single request-response
Example attack scenarios

Scenario 1: An attacker uploads a large image by issuing a POST request to /api/v1/images. When the upload is complete, the API creates multiple thumbnails with different sizes. Due to the size of the uploaded image, available memory is exhausted during the creation of thumbnails, and the API becomes unresponsive.

Scenario 2: We have an application that contains the users list on a UI with a limit of 200 users per page. The users' list is retrieved from the server using the following query: /api/users?page=1&size=200. An attacker changes the size parameter to 200 000, causing performance issues on the database. Meanwhile, the API becomes unresponsive and is unable to handle further requests from this or any other clients (aka DoS). The same scenario might be used to provoke Integer Overflow or Buffer Overflow errors.

Remedy suggestions
  • Docker makes it easy to limit memory, CPU, number of restarts, file descriptors, and processes.
  • Implement a limit on how often a client can call the API within a defined timeframe.
  • Notify the client when the limit is exceeded by providing the limit number and the time at which the limit will be reset.
  • Add proper server-side validation for query string and request body parameters, specifically the one that controls the number of records to be returned in the response.
  • Define and enforce the maximum size of data on all incoming parameters and payloads, such as the maximum length for strings and the maximum number of elements in arrays.