Skip to main content

Insecure session management - Change Password

Need

Secure session management after a password change

Context

  • Usage of Dart 2.0 for building high-performance, cross-platform applications
  • Usage of Shelf for managing and organizing data in a Node.js application
  • Usage of shelf_io for managing input and output operations in a Node.js application

Description

Non compliant code

import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as io;

void main() {
var handler = const shelf.Pipeline().addMiddleware(shelf.logRequests())
.addHandler(_echoRequest);

io.serve(handler, 'localhost', 8080).then((server) {
print('Serving at http://${server.address.host}:${server.port}');
});
}

shelf.Response _echoRequest(shelf.Request request) {
if (request.url.path == 'changePassword') {
var newPassword = request.headers['new-password'];
// Assuming we have a function that can change the password
changePassword(newPassword);
return new shelf.Response.ok('Password changed successfully');
}
return new shelf.Response.notFound('Not Found');
}

void changePassword(String newPassword) {
// Change the password in the database
}

The above code is a simple server that listens for requests and changes a user's password when a changePassword request is received. The new password is taken from the new-password header of the request.

The vulnerability lies in the fact that after the password is changed, the existing session remains open. This is insecure because if an attacker has somehow gained access to the user's session (for example, through session hijacking), they can continue to use the session even after the user has changed their password.

In a secure application, the session should be invalidated after a password change to ensure that any potential attacker is immediately logged out. This can be done by adding a invalidateSession function that is called immediately after the password is changed.

Steps

  • Create a session management system that can handle session invalidation.
  • After the password change, invalidate the current session.
  • Force the user to log in again with the new password, creating a new session.

Compliant code

import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as io;

void main() {
var handler = const shelf.Pipeline().addMiddleware(shelf.logRequests())
.addHandler(_echoRequest);

io.serve(handler, 'localhost', 8080).then((server) {
print('Serving at http://${server.address.host}:${server.port}');
});
}

shelf.Response _echoRequest(shelf.Request request) {
if (request.url.path == 'changePassword') {
var newPassword = request.headers['new-password'];
// Assuming we have a function that can change the password
changePassword(newPassword);
// Invalidate the current session
invalidateSession(request);
return new shelf.Response.ok('Password changed successfully. Please log in again.');
}
return new shelf.Response.notFound('Not Found');
}

void changePassword(String newPassword) {
// Change the password in the database
}

void invalidateSession(shelf.Request request) {
// Invalidate the current session in the session management system
}

The updated code includes a session management system that invalidates the current session after a password change. This is done by calling the invalidateSession(request) function after the password has been changed.

The invalidateSession(request) function should contain the logic to invalidate the current session in the session management system. This function is not implemented in this code snippet, as it would depend on the specific session management system used.

After the session has been invalidated, the user is forced to log in again with the new password, creating a new session. This is communicated to the user by changing the response message to 'Password changed successfully. Please log in again.'.

This change fixes the insecure session management vulnerability by ensuring that an old session cannot be used after a password change.

References