Insecure session management - Change Password - TypeScript

Insecure session management - Change Password - TypeScript

Need

Secure session management after password changes

Context

  • Usage of TypeScript for statically typed JavaScript development
  • Usage of Express for building web applications and APIs
  • Usage of express-session for managing user sessions in Express applications

Description

Non compliant code

        import express from 'express';
import session from 'express-session';

const app = express();

app.use(session({
  secret: 'mysecretkey',
  resave: false,
  saveUninitialized: false
}));

app.post('/change-password', (req, res) => {
  // Change password logic here

  // Insecure session management vulnerability
  // Session remains open after password change
  res.send('Password changed successfully');
});

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

The vulnerability in this code is an insecure session management issue related to the change password functionality.

In the code, an Express application is created and an Express session middleware is used to handle session management. The session middleware is configured with a secret key, and the options resave and saveUninitialized are set to false.

The vulnerability occurs in the /change-password route handler. After the password change logic is executed, the server sends a response with the message "Password changed successfully". However, the session is not closed or invalidated after the password change, allowing the session to remain open.

This vulnerability can have a significant impact as it allows an attacker who has compromised a user's session to retain control of the account even after the password has been changed. The attacker can continue to perform actions on behalf of the user, potentially leading to unauthorized access and misuse of the account.

To mitigate this vulnerability, the open session should be closed or invalidated after the password change process. This can be done by destroying the session or resetting the session ID to prevent further use of the old session.

Steps

  • After the password change logic, add a line of code to destroy the session using req.session.destroy()
  • This will ensure that the session is closed and a new session is created after the password change

Compliant code

        import express from 'express';
import session from 'express-session';

const app = express();

app.use(session({
  secret: 'mysecretkey',
  resave: false,
  saveUninitialized: false
}));

app.post('/change-password', (req, res) => {
  // Change password logic here

  // Insecure session management vulnerability
  // Session remains open after password change
  req.session.destroy(); // Destroy the session after password change

  res.send('Password changed successfully');
});

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

The fixed code addresses the vulnerability by ensuring that the session is closed after a password change process.

First, the code imports the necessary modules, 'express' and 'express-session'.

Then, an instance of the Express application is created using the express() function and stored in the 'app' variable.

The code sets up session management by using the 'express-session' middleware. The session middleware is configured with a secret key, which is used to sign the session ID cookie, and the options 'resave' and 'saveUninitialized' are set to false. This ensures that the session is not saved for every request and that a new session is not created for every request.

Next, the code defines a route handler for the '/change-password' endpoint using the app.post() method. Inside the route handler, the logic for changing the password is implemented.

To address the vulnerability, the code includes the line 'req.session.destroy();' after the password change logic. This line destroys the session, effectively closing it after the password change process.

Finally, the code sends a response to the client indicating that the password has been changed successfully.

The application listens on port 3000 using the app.listen() method and logs a message to the console when the server is running.

References