Rate limiting

A way to avoid too many requests at once from a single source.

If a malicious person wishes, they can bombard our server with requests, throttling it. Fortunately, it's quite simple to avoid this kind of situation. Nest has integration with a Throttler, which limits the amount of requests that a route may receive in a time interval from the same source. This process is called Rate Limiting.

First, we should install it.

yarn add @nestjs/throttler

Then, create variables in .env and .env.example to store the options we'll use for the throttler.

THROTTLER_TTL = 60
THROTTLER_LIMIT = 10

With this, when a request arrives, it is "remembered" for the time defined in TTL. If the amount of requests from the same source reaches the value of LIMIT, no more requests will be accepted until old ones are "forgotten" first. Roughly speaking, this means that, in each route, for a time interval of 60 seconds, only 10 requests from the same source will be accepted.

Proceeding, add them to the validation schema accordingly.

Joi.number().integer().positive().required(),

Finally, create its configuration namespace in auth -> config -> throttler.config.

export default registerAs('throttler', () => {
  const config = [
    {
      ttl: seconds(+process.env.THROTTLER_TTL),
      limit: +process.env.THROTTLER_LIMIT,
    },
  ] as const satisfies ThrottlerModuleOptions;
  return config;
});

Note that:

  • The variables must be cast to number, as they are strings

  • The ttl is converted from seconds to ms (the used format)

  • The options object should be put inside an array

Then, in the imports of the AuthModule, we can add the ThrottlerModule.

ThrottlerModule.forRootAsync(throttlerConfig.asProvider()),

After this, in the providers of the AuthModule, we can enable the ThrottlerGuard globally, before the other guards.

{
  provide: APP_GUARD,
  useClass: ThrottlerGuard,
},

We can also have finer control over this process if desired, using decorators that change a specific behavior for a certain route or controller. For example:

  • @SkipThrottle() - Disables the throttler (may receive false to not disable it)

  • @Throttle() - Overrides the values of ttl and limit

Commit - Using rate limiting to protect against brute force attacks

Last updated