Skip to main content

Asymmetric denial of service

Need

The need is to implement measures that protect the server from asymmetric denial of service attacks, ensuring its availability and preventing resource exhaustion.

Context

  • Usage of TypeScript for type-checking and compiling JavaScript code
  • Usage of Express for building web applications and APIs

Description

Non compliant code

import express from 'express';

const app = express();

app.get('/vulnerable', (req, res) => {
// Simulate an amplification attack by sending multiple responses
for (let i = 0; i < 100000; i++) {
res.send('Amplification response');
}
});

app.get('/dos', (req, res) => {
// Simulate a denial of service attack by consuming a lot of resources
while (true) {
// Consuming resources indefinitely
}
});

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

The vulnerability in the provided code is an asymmetric denial of service vulnerability.

In the /vulnerable route, the code simulates an amplification attack by sending multiple responses in a loop. This means that for every request made to this route, the server will send a large number of responses, potentially overwhelming the server's resources and making it unresponsive. This can lead to a denial of service situation where legitimate users are unable to access the application services.

In the /dos route, the code simulates a denial of service attack by consuming a lot of resources indefinitely. The code enters an infinite loop, continuously consuming resources without any termination condition. This can cause the server to become unresponsive and deny access to legitimate users.

Both of these vulnerabilities can lead to a denial of service situation, where the server becomes unresponsive or crashes, denying access to the application services.

To mitigate these vulnerabilities, it is recommended to define a timeout when a query or search is taking a lot of time processing the information. This will ensure that if a request is taking an unusually long time, it will be terminated, preventing the server from being overwhelmed or consuming excessive resources.

Steps

  • Identify the vulnerable code segments that are causing the amplification attack and denial of service attack.
  • For the '/vulnerable' route, remove the loop that sends multiple responses. Instead, send a single response and limit the number of responses sent.
  • For the '/dos' route, remove the infinite loop that consumes resources indefinitely. Instead, implement a timeout mechanism to limit the amount of time the route can consume resources.
  • Define a reasonable timeout duration for both routes to prevent excessive resource consumption.
  • Test the updated code to ensure that the amplification attack and denial of service attack are no longer possible.

Compliant code

import express from 'express';

const app = express();

app.get('/vulnerable', (req, res) => {
// Send a single response instead of multiple responses
res.send('Amplification response');
});

app.get('/dos', (req, res) => {
// Set a timeout to limit the amount of time the route can consume resources
setTimeout(() => {
res.send('Denial of service response');
}, 5000); // Set a reasonable timeout duration (e.g., 5 seconds)
});

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

The fixed code is written in TypeScript and uses the Express framework to create a server. It addresses the vulnerability by implementing two routes: '/vulnerable' and '/dos'.

In the '/vulnerable' route, the server sends a single response instead of multiple responses. This prevents an amplification attack where a single request could result in multiple responses, overwhelming the server. By sending only one response, the server avoids being rendered unresponsive.

In the '/dos' route, a timeout is set to limit the amount of time the route can consume resources. The setTimeout function is used to delay the sending of the response by 5 seconds (5000 milliseconds). This ensures that the route does not consume an enormous amount of resources and prevents a single malicious request from causing a denial of service.

By implementing these measures, the fixed code mitigates the vulnerability by preventing the server from being overwhelmed or rendered unresponsive.

References