Insecure object reference - User deletion - Dart

Insecure object reference - User deletion - Dart

Need

Secure user deletion process and session management

Context

  • Usage of Dart for building cross-platform mobile, web, and desktop applications
  • Usage of Shelf for managing data persistence and querying in Node.js

Description

Non compliant code

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

class UserController {
  Map users = {...};

  shelf.Response deleteUser(shelf.Request request) {
    // Extract the user id from the request
    final userId = request.url.queryParameters['userId'];

    // Delete the user from the map
    users.remove(userId);

    // Return a successful response
    return shelf.Response.ok('User deleted successfully');
  }
}
        
        

In the above code snippet, we have a UserController class which has a deleteUser method. This method takes a shelf.Request object, extracts the userId from the request query parameters and removes the user with that id from the users map.

There are two main vulnerabilities in this code:

1. Insecure Direct Object References (IDOR): The userId is directly used from the request without any validation or access control checks. This means any user can delete any other user just by knowing their userId. This can lead to unauthorized deletions, making the system inoperative and affecting its integrity to a high degree.

2. Session Management: After the user is deleted, the session is not invalidated. This means the deleted user can still continue to browse the application until their session expires. This is a serious security flaw as it can lead to unauthorized access and actions.

To fix these vulnerabilities, we need to implement proper access control checks to ensure that only authorized users can delete users. Additionally, we need to invalidate the session of the deleted user to prevent further actions.

Steps

  • Validate the user ID from the request to ensure it exists in the users map before attempting to delete.
  • Implement an authorization check to ensure the user making the request has the necessary permissions to delete users.
  • After deleting a user, invalidate their session to prevent them from continuing to browse the application.
  • Consider implementing a soft delete mechanism, where users are marked as deleted but not actually removed from the system. This can help maintain system integrity.

Compliant code

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

class UserController {
  Map users = {...};
  Map sessions = {...};

  shelf.Response deleteUser(shelf.Request request) {
    // Extract the user id from the request
    final userId = request.url.queryParameters['userId'];

    // Check if the user exists
    if (!users.containsKey(userId)) {
      return shelf.Response.notFound('User not found');
    }

    // Check if the user has the necessary permissions to delete users
    if (!request.context['user'].hasPermission('delete_users')) {
      return shelf.Response.forbidden('You do not have permission to delete users');
    }

    // Invalidate the user's session
    sessions.remove(userId);

    // Soft delete the user
    users[userId].isDeleted = true;

    // Return a successful response
    return shelf.Response.ok('User deleted successfully');
  }
}
        
        

The updated code includes several security enhancements to address the insecure object reference vulnerability:

1. User Existence Check: Before attempting to delete a user, the code now checks if the user exists in the users map. If the user does not exist, the function returns a 404 Not Found response.

2. Authorization Check: The code now checks if the user making the request has the necessary permissions to delete users. This is done by checking the delete_users permission on the user object stored in the request context. If the user does not have this permission, the function returns a 403 Forbidden response.

3. Session Invalidating: After deleting a user, the code now invalidates their session by removing it from the sessions map. This prevents the deleted user from continuing to browse the application.

4. Soft Deletion: Instead of completely removing the user from the users map, the code now implements a soft delete mechanism. The isDeleted property of the user object is set to true, marking the user as deleted but not actually removing them from the system. This helps maintain system integrity by preserving the user's data and history.

References