Skip to main content

Improper control of interaction frequency

Need

Enforce rate limiting to control the frequency of user interactions

Context

  • Usage of TypeScript for statically typed JavaScript development
  • Usage of Express for building web applications and handling HTTP requests

Description

Non compliant code

import express from 'express';

const app = express();

app.get('/api/posts', (req, res) => {
// Handle request logic
});

app.listen(3000, () => {
console.log('Server is running on port 3000');
});

The vulnerability in the given code is that it does not implement any rate limiting mechanism. This means that there is no restriction on the number of requests that a user can make to the server within a short period of time.

Without rate limiting, an attacker can potentially flood the server with a large number of requests, overwhelming its resources and causing a denial of service. Additionally, this can also fill up the application logs with unnecessary and potentially malicious information.

To mitigate this vulnerability, it is recommended to implement rate limiting by setting a maximum number of requests that can be made by the same host within a defined time period. This can help prevent abuse and protect the server from being overwhelmed.

Steps

  • Implement rate limiting middleware to limit the number of requests per host in a defined time period.
  • Add a configuration option to specify the maximum number of requests allowed per host.
  • Use a data store (e.g., Redis) to store the request count for each host.
  • Create a middleware function that checks the request count for the host and rejects the request if it exceeds the limit.
  • Apply the rate limiting middleware to the appropriate routes in the application.
  • Test the application to ensure that the rate limiting is working correctly.

Compliant code

import express from 'express';
import rateLimit from 'express-rate-limit';

const app = express();

// Rate limiting configuration
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // maximum 100 requests per windowMs
});

// Apply rate limiting middleware to the appropriate routes
app.use('/api/posts', limiter);

app.get('/api/posts', (req, res) => {
// Handle request logic
});

app.listen(3000, () => {
console.log('Server is running on port 3000');
});

The fixed code addresses the vulnerability by implementing rate limiting using the express-rate-limit middleware.

First, the code imports the necessary modules express and express-rate-limit.

Then, an instance of the express application is created.

Next, the code configures the rate limiting by creating a limiter object using the rateLimit function. The windowMs property is set to 15 minutes, which defines the time window for rate limiting. The max property is set to 100, which limits the maximum number of requests per windowMs time window.

The rate limiting middleware is then applied to the appropriate route, in this case, the /api/posts route, using the app.use method.

Finally, a GET route handler is defined for the /api/posts route, where the actual request logic can be implemented.

The server is started on port 3000 using the app.listen method.

With this implementation, any requests made to the /api/posts route will be subject to rate limiting. If a user exceeds the maximum number of requests within the defined time window, subsequent requests will be blocked or delayed, preventing the system from being overwhelmed and protecting against potential denial of service attacks.

References