Last Updated on February 11, 2024

HTTP flood attacks are distributed denial-of-service attacks (DDoS), having for goal to make a website or web application unavailable to legitimate users by overwhelming the web server with a large number of HTTP requests. 

In order to conduct the attack, the attacker sends resource-intensive requests to the target website. The goal of this action is to exhaust the capacity of the web server. Furthermore, while the server is using all available resources to process these malicious requests, it will not be able to process requests coming from legitimate users. This affects the availability of the web server for regular business use cases.

Http flood attack
HTTP flood attack with a botnet

The most common HTTP verbs used by attackers are GET and POST. Which makes sense since these two are the most used verbs on the internet.

It’s very difficult to prevent DDoS attacks, but there are some techniques that you can use to mitigate these attacks. We will go through some of these best practices in this article. But before getting there, let’s make sure you understand the difference between these two terms: DoS and DDoS.  

What is a DoS attack?

A denial-of-service (DoS) attack is a malicious tentative from a cyber threat actor to take down a network component or an entire network. A network component can be a router or any server providing resources on the network, such as an email server, a file server, a web server, or even a DNS server. The goal of this attack is to affect the availability of the targeted resource and therefore disrupt the business or service offered by this resource.

Nevertheless, history has proven that DoS attacks can also be used as diversions for much larger attacks. In these cases, the goal is to distract the security engineers while a much larger attack is taking place. This is why it’s important to detect these attacks earlier.

There is a variety of techniques available to conduct DoS attacks. Here are some of the famous DoS attacks:

Http flood attacks

An HTTP flood attack is a specialized attack where the attacker sends a huge amount of packets to a host, beyond the capacity that this host can handle. HTTP flood and ping flood are variants of the flood attack.

SYN flood

In this technique, the attacker starts the process to open many TCP connections but never completes the TCP 3-way handshake. Therefore, the server ends up with many half-opened TCP sessions that are consuming network resources.

Ping of death

Ping of death is the act of sending a malformed or malicious ping packet to a target machine. This can cause the target machine to crash or to have a weird behavior after processing the malformed packet.

Buffer overflow attack

The act of sending a large amount of data to a host in order to create a memory buffer overflow. A buffer overflow can cause the system to eventually crash.

Permanent DoS

Permanent DoS happens when the attacker exploits a vulnerability in a network device to break into it and reflash the firmware. In such a case, the device goes offline completely and cannot boot anymore.

What is a DDoS?

Usually, in order to cover their tracks,  attackers conduct DoS attacks from compromised machines that are under their command-and-control spell (i.e. a zombie machine).  The more machines the attacker has under control, the more effective the DoS attack is. This is where the term ‘Distributed Denial of Services (DDoS)‘ comes into play.

In a DDoS attack, the attacker uses a group of compromised systems, also known as a botnet, to attack simultaneously the target machine. This strategy amplifies the effect of the denial-of-service attack.

Basically, DoS attacks come from 1 machine, but DDoS attacks come from multiple machines. That’s the difference between DoS and DDoS. The GitHub attack in 2018 is a real-world example of a DDoS that made GitHub services unavailable for 10 minutes.

With the rise of the Internet of Things (IoT), billions of devices are now connected to the Internet. Unfortunately, many of those devices are not configured correctly. This is also one of the reasons why some security experts ironically call these devices the “Internet of Insecure Things“. For example, some of these connected devices still use the default password. Therefore, attackers have more and more devices available to them to conduct DDoS attacks. So, it’s possible that your connected fridge participates in a DDoS in the future. According to Cisco, these attacks will double from 2018 to 2023 (i.e 15.4 million DDoS attacks by 2023 globally).

That being said, what can we do to mitigate these attacks? Well, let’s take a look at the mitigation techniques for HTTP flood attacks.

10 tips to mitigate HTTP flood attacks

Tip #1: Authenticate users

It’s always a good practice to make your web application available only to authenticated users. There are many authentication mechanisms that you can use: Username/Password, OAuth 2.0, OpenId Connect, API Keys,…

At first, your web application verifies the identity of the person calling the API. Then, it makes sure that the authenticated user has the rights to access the requested information (i.e authorization process). The authorization decision can also be based on the attributes of the authenticated user. For example, you might decide that only members of a specific user group have access to certain resources.

The idea here is to reject all requests coming from either unauthenticated or unauthorized users. Therefore, these requests will consume a limited amount of CPU and memory, compared to the requests that are accepted by the web server (i.e. especially for resource-intensive requests).

Furthermore, it’s even better to use an authentication process that enforces multi-factor authentication (MFA). This way, manual action is required from users during the authentication process before accessing the website.

Of course, authentication by itself is not a preventive measure against HTTP flood attacks. It just gives more work to the attacker because, in order to send many resource-intensive requests to the server, the attacker needs to have access to user credentials or authentication tokens.

Nonetheless, it’s still possible to exhaust a web server with unauthenticated requests. The attacker can still send terabytes of malicious data to your server, just to create network congestion. But that requires the attacker to have more devices in his botnet, which again requires more work on his side.

Therefore, if possible, secure your web application with authentication and authorization.

Tip #2: Rate limiting is your friend

When dealing with HTTP flood attacks, it’s very difficult to differentiate malicious requests from valid traffic. Rate limiting is a protection measure that you can put in place to protect your server from excessive usage. These excessive API calls can come from a legitimate user as well.

Rate limiting helps to prevent server and network resource exhaustion. This mechanism consists of putting in place a constraint about the acceptable number of requests per client or user. As an example, you can decide that no client should make more than 100 requests per minute to your web server. When this limit is reached, the service returns an error to the API caller (e.g. HTTP status 429 – Too Many Requests).

Most rate limiting techniques identify the caller with its IP address. Therefore, in general, the limit applies to the client and not to a specific user. However, some implementation gives the possibility to apply rate limiting based on a specific HTTP header. 

Tip #3: Reduce the maximum request size

The goal of HTTP flood attacks is to consume resources on the web server and create congestion in the network. Therefore, you don’t want to accept a large amount of data from API callers if not necessary.

For example, let’s say you are offering a POST request that allows users to upload a file to the server. For this use case, it’s recommended to put a hard limit on the size of the file. Therefore, you can configure the maximum request body size at the entry point of your web server, to ensure that all requests containing more data will not be processed by your application code.

If you’re using Asp.Net core with Kestrel, the default maximum request body size is 30 MB. This value is configurable in the code or in the web.config file.

So, do not hesitate to reduce this setting if the default value doesn’t make sense for your business case.

Tip #4: Leverage caching

Website caching or content caching is an optimization technique to reduce the CPU time used to process HTTP requests. Basically, caching allows you to improve the overall performance of your website. For that reason, caching can be helpful during a DDoS attack, to spare resource utilization.

 The most common caching strategy is to send directives to the client through the cache-control header (i.e client-side caching). But, to be more effective, you cannot rely only on client-side caching. You need to leverage server-side caching as well.

Here are the different layers of server-side caching that you can use:

In-Memory cache

This type of cache is practical to temporarily save the result of a CPU-intensive computation. In-memory caching software like Memcached, are also useful to improve the response time of database queries.

Static files cache

It’s recommended to serve static files (e.g images, CSS, scripts)  from a content delivery network (CDN). Usually, CDN providers have a distributed network around the world and are able to leverage caching in their datacenters.

By serving your static files through a CDN, you are offloading the bandwidth requirements to the CDN provider.

Server-side page or content cache

This is a server-side caching technique that you can use to optimize resource usage. These techniques can be used to improve the number of requests that the web server can handle in a specified timeframe.

In ASP.NET Core, you can use the response caching middleware.

Tip #5: Stop processing a request when the client closes the TCP connection

Since servers’ resources are limited, one of the best practices consists of avoiding the unnecessary usage of those resources.

In the scenario where a client sends an HTTP request and closes the underlying TCP connection before receiving the response, the server should stop processing the request, especially if it’s a CPU intensive request.

If you are using ASP.NET Core, you can check if the request is aborted by verifying the RequestAborted property of the HttpContext. It’s also possible to use the CancellationToken object at the controller level.

Tip #6: Implement a Challenge-Response mechanism for specific operations

A challenge-response is a sort of authentication mechanism that consists of presenting a challenge to the user before processing his requests. Usually, the challenge-response strategy requires manual interaction from the user. It’s a mechanism that makes it more difficult for devices belonging to a botnet to flood the server with HTTP requests.

A famous example of this mechanism is the Completely Automated Public Turing test to tell Computers and Humans Apart (CAPTCHA). It verifies if there is a human behind the computer by asking the person to resolve a challenge. An example of such a challenge includes identifying objects in different images. The resolution of the challenge increases the probability that the entity driving the operation is not a machine. This technique is used to protect sensitive or resource-intensive operations.

Tip #7: Use exponential backoff when retrying backend operations

Usually, web servers need to access external resources over the network, like a database for example. In such cases, developers will implement a retry mechanism in case an external dependency is temporarily unable (i.e transient failure). There are many open-source libraries that you can use to implement a retry mechanism in your code. If you are using the .NET framework, Polly is one of those libraries.

When implementing a retry mechanism, you don’t want to use a fixed interval because that will just add more load to the overall system. Imagine if 1000 requests to the database fail because the database server doesn’t have the resources to process these requests. Retrying all these 1000 requests at the same time 30 seconds later will not help to decrease the load on the database server. This usually creates a self-inflicted DoS.

The best solution, in this case, is to use an exponential back-off mechanism. That means, you will wait for example 15 seconds before retrying a request, and then if it fails again, you wait 30 seconds, then 1 minute, 2 minutes. You get it, the goal here is to double the waiting interval between failures until you reach a specified limit (which depends on your business case). Also, the initial retry interval can be a random value between 5 and 15 seconds for example. This way you make sure that you don’t retry all these 1000 requests exactly at the same time.

Basically, exponential backoff is a powerful technique that can improve the performance of your server during congestion.

Tip #8: Install security updates on your server

This is the most basic operation that you need to do: making sure to have the latest security fixes installed on your server.

For example, in June 2020, Microsoft released an update of .Net Core 3.1 that includes fixes addressing a denial-of-service vulnerability.

Microsoft is aware of a denial of service vulnerability which exists when .NET Core improperly handles web requests. An attacker who successfully exploited this vulnerability could cause a denial of service against a .NET Core web application. The vulnerability can be exploited remotely, without authentication. 

So, if you are not using the latest version of .Net core 3.1, your system may be exposed to vulnerabilities that are fixed in the latest updates.

It’s always a good practice to update the runtimes and software that your web server uses.

Tip #9: Use a web application firewall (WAF)

A web Application Firewall is a reverse-proxy that analyze and filter HTTP, HTTPS or TLS traffic between your web application and the internet. It’s a firewall that has the capability to protect your web server from application-layer attacks such as SQL Injections, cross-site Scripting (XSS), and other OWASP Top Ten vulnerabilities.

Moreover, a WAF is able to build an IP reputation catalog, detect malicious behavior, and block clients based on real time analysis of the traffic. In a nutshell, a WAF can really be helpful to mitigate HTTP flood attacks and other DDoS attacks.

Tip #10: Leverage the cloud

From the DDoS perspective, there are many advantages to host your web application to the cloud:

  • Cloud providers usually offer DDoS prevention services for free. For example, Amazon offers AWS Shield with Amazon Web Services, and Microsoft offers the DDoS Basic protection at no additional cost.
  • Cloud providers offer a WAF component that you can include in the architecture of your solution.
  • Most of the time, the cloud has more bandwidth than on-premise networks, and bandwidth is crucial when dealing with DDoS attacks.
  • You can design your solution to scale out when there is more traffic. But you also have to be careful because this strategy can be costly if you don’t configure a maximum number of instances.

Therefore,  it’s a good strategy to leverage the cloud to host your web application.

That’s pretty much it…

By following these best practices, your web application will be more resilient and that will help to minimize downtime during a DDoS attack. Furthermore, you will also need to put in place a monitoring system to detect unusual activities in your system. By detecting DDoS attacks earlier, you increase your chance to mitigate these attacks.