Skip to main content

Insecure object reference - User deletion

Need

Protection against insecure object reference vulnerabilities in user deletion functionality

Context

  • Usage of TypeScript for statically typed JavaScript development
  • Usage of Express for building web applications and APIs

Description

Non compliant code

import express from 'express';

const app = express();

let users = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
{ id: 3, name: 'Alice' },
];

app.get('/users/:id', (req, res) => {
const userId = parseInt(req.params.id);
const user = users.find((u) => u.id === userId);

if (user) {
res.json(user);
} else {
res.status(404).json({ message: 'User not found' });
}
});

app.delete('/users/:id', (req, res) => {
const userId = parseInt(req.params.id);
const userIndex = users.findIndex((u) => u.id === userId);

if (userIndex !== -1) {
users.splice(userIndex, 1);
res.json({ message: 'User deleted successfully' });
} else {
res.status(404).json({ message: 'User not found' });
}
});

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

The vulnerability in this code is an insecure object reference.

In the /users/:id route, the code retrieves the user with the specified ID from the users array using the find method. However, there are no checks to ensure that the user requesting the information has the necessary permissions to access that user's data. This means that any user can access the details of any other user by simply providing the user ID in the request.

Similarly, in the /users/:id route, the code allows users to delete a user from the users array based on the provided ID. Again, there are no checks to ensure that the user making the request has the appropriate permissions to delete the user. This means that any user can delete any other user from the system, potentially causing data loss and disrupting the application's functionality.

Furthermore, after a user is deleted, the code does not invalidate the user's session. This means that the deleted user can still access the application and perform actions, which is a serious security flaw.

To mitigate this vulnerability, the code should implement proper authorization and authentication mechanisms to ensure that only authorized users can access and modify user data. Additionally, the code should invalidate the session of a deleted user to prevent further access to the application.

Steps

  • Implement authentication and authorization mechanisms to ensure that only authorized users can access the delete user endpoint.
  • When deleting a user, invalidate their session to prevent them from continuing to browse the application.
  • Consider implementing a soft delete mechanism instead of directly removing the user from the users array. This way, you can mark the user as deleted without permanently removing their data.
  • Update the delete user endpoint to check if the authenticated user has the necessary permissions to delete the user.
  • Consider logging the deletion of users for auditing purposes.

Compliant code

import express from 'express';

const app = express();

let users = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
{ id: 3, name: 'Alice' },
];

// Authentication and Authorization middleware
const authenticateUser = (req, res, next) => {
// Implement authentication logic here
// Check if the user is authenticated and has the necessary permissions
// You can use session tokens, JWT, or any other authentication mechanism
// If the user is authenticated and authorized, call next()
// Otherwise, return an error response
};

app.get('/users/:id', (req, res) => {
const userId = parseInt(req.params.id);
const user = users.find((u) => u.id === userId);

if (user) {
res.json(user);
} else {
res.status(404).json({ message: 'User not found' });
}
});

app.delete('/users/:id', authenticateUser, (req, res) => {
const userId = parseInt(req.params.id);
const userIndex = users.findIndex((u) => u.id === userId);

if (userIndex !== -1) {
// Invalidate user's session here
// Implement the logic to invalidate the session associated with the deleted user

// Soft delete the user instead of directly removing from the array
users[userIndex].deleted = true;

// Log the deletion of the user here
// Implement the logic to log the deletion of the user for auditing purposes

res.json({ message: 'User deleted successfully' });
} else {
res.status(404).json({ message: 'User not found' });
}
});

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

The fixed code addresses the vulnerability by implementing proper controls and safeguards to prevent unauthorized deletion of users. Here's an explanation of the changes made:

  1. Authentication and Authorization Middleware: A middleware function named authenticateUser is added to handle authentication and authorization. This function should be implemented to check if the user is authenticated and has the necessary permissions before allowing access to certain routes.

  2. GET /users/:id Route: This route retrieves user information based on the provided user ID. It checks if the user exists in the users array and returns the user object if found. Otherwise, it returns a 404 error indicating that the user was not found.

  3. DELETE /users/:id Route: This route handles the deletion of users. It first checks if the user exists in the users array by finding the index of the user with the provided ID. If the user is found, the code proceeds with the deletion process.

    • Session Invalidation: Before deleting the user, the code should implement the logic to invalidate the session associated with the deleted user. This ensures that the user's session is terminated, preventing them from continuing to browse the application.

    • Soft Deletion: Instead of directly removing the user from the users array, the code sets a deleted property on the user object to true. This allows for auditing purposes and maintains a record of the deleted user.

    • Logging: The code should implement the logic to log the deletion of the user for auditing purposes. This ensures that there is a record of user deletions and helps with tracking any suspicious activities.

    • Response: If the user is successfully deleted, the code returns a JSON response with a success message. If the user is not found, it returns a 404 error indicating that the user was not found.

By implementing these changes, the code ensures that only authenticated and authorized users can delete users. It also includes additional safeguards such as session invalidation and logging to maintain the integrity of the application.

References