Skip to main content

Improper resource allocation - Memory leak

Need

Proper resource management and deallocation

Context

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

Description

Non compliant code

import express from 'express';

const app = express();

app.get('/leak', (req, res) => {
const data = [];
setInterval(() => {
for (let i = 0; i < 100000; i++) {
data.push('leak');
}
}, 1000);

res.send('Memory leak vulnerability');
});

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

The vulnerability in the provided code is an improper resource allocation, specifically a memory leak.

In the code, an Express server is created and a route is defined for the '/leak' endpoint. Inside the route handler, a setInterval function is used to repeatedly execute a loop that pushes the string 'leak' into an array called 'data'.

The issue is that the setInterval function is not explicitly stopped or cleared, which means that it will continue to run indefinitely, causing the 'data' array to grow continuously. This leads to a memory leak because the system is not able to release the memory allocated for the 'data' array, resulting in the exhaustion of server resources over time.

To fix this vulnerability, the setInterval function should be explicitly stopped or cleared when it is no longer needed. This can be done by assigning the setInterval function to a variable and then calling clearInterval on that variable when necessary.

Steps

  • Identify the resource that is not being properly released.
  • In this case, the resource is the interval created by setInterval().
  • Add a variable to store the interval ID.
  • Assign the interval ID to the variable when creating the interval.
  • Call clearInterval() with the interval ID to stop the interval when it is no longer needed.
  • In this case, the interval should be stopped when the '/leak' route handler is finished.
  • Update the code to stop the interval before sending the response.
  • The updated code should look like this:

Compliant code

import express from 'express';

const app = express();

app.get('/leak', (req, res) => {
const data = [];
const intervalId = setInterval(() => {
for (let i = 0; i < 100000; i++) {
data.push('leak');
}
}, 1000);

res.send('Memory leak vulnerability');

clearInterval(intervalId);
});

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

The fixed code addresses the memory leak vulnerability by explicitly shutting down the resource allocation after use.

In the code, we import the Express framework and create an instance of the application using express().

We define a route for '/leak' using app.get() method. Inside the route handler, we initialize an empty array called data and a variable intervalId to store the ID of the setInterval function.

Within the setInterval function, we have a loop that pushes the string 'leak' into the data array. This loop runs every 1000 milliseconds (1 second).

After defining the setInterval function, we send a response to the client with the message 'Memory leak vulnerability' using res.send().

To fix the memory leak vulnerability, we add clearInterval(intervalId) after sending the response. This ensures that the setInterval function is stopped and the resources are released.

Finally, we start the server to listen on port 3000 using app.listen(). When the server starts, it logs a message 'Server started on port 3000' to the console.

By explicitly shutting down the resource allocation after use, the fixed code prevents the accumulation of resources and avoids exhausting the server resources.

References