DEV Community

Cover image for 71-Nodejs Course 2023: Request Throttle, Rate Limiters and DDOS Attacks
Hasan Zohdy
Hasan Zohdy

Posted on

71-Nodejs Course 2023: Request Throttle, Rate Limiters and DDOS Attacks

Introduction

You may (or may not) have come across the keyword throttle or rate-limit in the context of Nodejs, but what does it mean? In this article, we will learn about throttling and how to implement it later in our code.

What is throttling?

Throttling is a technique used to limit the number of requests that can be made to a server in a given time period. It is used to prevent a server from being overloaded by too many requests. It is also used to prevent a server from being attacked by a bot, that attack is called DDoS (Distributed Denial of Service) attack.

What is DDOS attack?

Let’s back up for a second. What is a DDoS attack? *DDoS stands for “distributed denial of service”, which is a type of cyberattack that forces people offline. Hackers’ goals in committing DDoS attacks are to flood a network with unwanted requests and traffic. Subsequently, a site can’t handle the influx any further, preventing legitimate traffic from coming through.

How does this work?

Let's say we have a server that is handling requests from a client. The client is making requests to the server at a rate of 100 requests per second. If we don't have any throttling mechanism, the server will be overloaded and will not be able to handle the requests thus the server will get crashed. So, we need to limit the number of requests that can be made to the server in a given time period. Let's say we limit the number of requests to 10 per second. So, the client will be able to make 10 requests per second and the server will be able to handle the requests.

We can refer to it as well as a rate limiter.

This is a kind of middleware, don't forget that as it interacts with the request before it reaches the route handler.

How to implement throttling?

We can do it by our own, but i'll use for now Fastify-rate-limit plugin to achieve this easily.

Installing Fastify-rate-limit

Open up your terminal and run the following command to install the plugin.

yarn add @fastify/rate-limit
Enter fullscreen mode Exit fullscreen mode

Using Fastify-rate-limit

We already have the plugins.ts file in our http directory, so we can just call the plugin from there.

// src/core/http/plugins.ts
import fastifyJwt from "@fastify/jwt";
import fastifyMultipart from "@fastify/multipart";
import { registerPlugin } from "./server";

// Note the change that we made in the function definition, i added `async` keyword
export default async function registerHttpPlugins() {
  // 👇🏻 register rate-limit plugin
  await registerPlugin(import("@fastify/rate-limit"), {
    // max requests per time window
    max: 100,
    // maximum time that is will allow max requests
    timeWindow: "1 minute",
  });

  // import multipart plugin
  registerPlugin(fastifyMultipart, {
    attachFieldsToBody: true,
  });

  // use the jwt plugin with your preferred secret key
  registerPlugin(fastifyJwt, {
    secret: "my-secret",
  });
}
Enter fullscreen mode Exit fullscreen mode

Actually i didn't know until this very moment that we can use import() in the registerPlugin function. I thought we can only use require() there or static import. But it turns out that we can use import() there as well, this will help us later to control which plugins to be used based on our later http configurations upgrade.

So we registered our plugin, and defined our max and timeWindow options, as using the plugin directly in the server instance, we don't need a middleware for that, but we can manage it later to be a good middleware too.

But to make this works, we need also tm await our registerHttpPlugins function in the src/core/http/connectToServer.ts file.

// src/core/http/connectToServer.ts
import config from "@mongez/config";
import router from "core/router";
import registerHttpPlugins from "./plugins";
import response from "./response";
import { getServer } from "./server";

export default async function connectToServer() {
  const server = getServer();

  // 👇🏻 await the registerHttpPlugins function
  await registerHttpPlugins();

  // call reset method on response object to response its state
  server.addHook("onResponse", response.reset.bind(response));

  router.scan(server);

  try {
    // 👇🏻 We can use the url of the server
    const address = await server.listen({
      port: config.get("app.port"),
      host: config.get("app.baseUrl"),
    });

    console.log(`Start browsing using ${address}`);
  } catch (err) {
    console.log(err);

    server.log.error(err);
    process.exit(1); // stop the process, exit with error
  }
}
Enter fullscreen mode Exit fullscreen mode

Testing the plugin

Let's test our plugin, let's decrease the max value to 10 and now let's write a little script to test our plugin.

We'll use it with our /users route but we'll need to stop the middleware now so we can test this in our browser.

Don't forget to comment the middleware in src/config/http file.

Now open your browser, then Press F12 or Ctrl + Shift + I to open the developer tools, then go to the console tab, then paste the following code.

async function main() {
  for (let i = 0; i < 20; i++) {
    try {
      const res = await fetch("http://localhost:3000/users");
      const content = await res.json();
      console.log('#' + i, content);
    } catch (err) {
      console.log(err);
    }
  }
}

main();
Enter fullscreen mode Exit fullscreen mode

Now you should see the following output in your console.

Throttling

And that's it.

Will throttling prevent DDOS attacks?

No, it will not. Throttling will only prevent the server from being overloaded by too many requests. It will not prevent the server from being attacked by a bot, the idea here is to blacklist the IP address of the bot, so that it cannot send any more requests to the server.

What if the bot uses a proxy or a VPN?

If the bot uses a proxy or a VPN, then it will have a different IP address, so it will not be blacklisted. The only way to prevent the bot from sending requests to the server is to use a captcha, which is a challenge-response test that is used to determine whether the user is human or not.

A New Security Risks course on the way

Actually, i'm going to make a new series that will introduce variant types of attacks and how to make your code more secure against them, such as top 10 security vulnerabilities which are called OWASP Top 10, and how to prevent them, and how to make your code more secure against them, the top 2021 security risks are:

  1. Broken Access Control
  2. Cryptographic Failures
  3. Injection
  4. Insecure Design
  5. Security Misconfiguration
  6. Vulnerable and Outdated Components
  7. Identification and Authentication Failures
  8. Software and Data Integrity Failures
  9. Security Logging and Monitoring Failures
  10. Server Request Forgery

This list will be demonstrated later in our new course, we'll start with a basic introduction to security risks and concepts such as:

  • What is a security risk?
  • What is a vulnerability?
  • What is a threat?
  • What is a risk?
  • What is a security risk assessment?
  • What is a security risk management?
  • What is a security risk analysis?
  • What is a security risk mitigation?
  • What is a security risk treatment?
  • What is a security risk assessment report?

Then we'll go with simple and very common security risks such as:

  • Brute force attacks
  • SQL injection
  • Cross-site scripting (XSS)
  • Cross-site request forgery (CSRF)
  • DoS Attacks (Denial of Service) and DDoS Attacks (Distributed Denial of Service)
  • Clickjacking
  • Backdoors
  • Buffer overflow
  • Command injection
  • Cookie poisoning
  • Directory traversal
  • Exploits
  • Honey pots
  • Man In The Middle (MITM)
  • Phishing
  • Session hijacking
  • Spoofing
  • Trojans
  • Vulnerabilities
  • Worms
  • Zero-day attacks
  • Zero-day vulnerabilities

We'll also learn how to use VPN cloud services such as Cloudflare to protect our servers from attacks.

And more, Stay tuned!

🎨 Conclusion

In this article, we learned about throttling and rate-limit concepts and how to implement it in our code. We used the @fastify/rate-limit plugin to achieve this easily.

We can later make it more configurable either in the config file or in middlewares or even in each route.

☕♨️ Buy me a Coffee ♨️☕

If you enjoy my articles and see it useful to you, you may buy me a coffee, it will help me to keep going and keep creating more content.

🚀 Project Repository

You can find the latest updates of this project on Github

😍 Join our community

Join our community on Discord to get help and support (Node Js 2023 Channel).

🎞️ Video Course (Arabic Voice)

If you want to learn this course in video format, you can find it on Youtube, the course is in Arabic language.

📚 Bonus Content 📚

You may have a look at these articles, it will definitely boost your knowledge and productivity.

General Topics

Packages & Libraries

React Js Packages

Courses (Articles)

Top comments (0)