Privilege escalation - TypeScript

Privilege escalation - TypeScript

Need

Enhancement of role-based access control to prevent unauthorized privilege escalation

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();

app.get('/admin', (req, res) => {
  if (req.query.role === 'admin') {
    res.send('Welcome, admin!');
  } else {
    res.send('Access denied!');
  }
});

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

The vulnerability in this code is a privilege escalation vulnerability.

In the code, there is a route defined for the '/admin' endpoint. When a GET request is made to this endpoint, the code checks the value of the 'role' query parameter. If the value is 'admin', it sends a response with the message 'Welcome, admin!'. Otherwise, it sends a response with the message 'Access denied!'.

The issue with this code is that it relies solely on the value of the 'role' query parameter to determine if the user should have administrative access. This means that any user can potentially modify the query parameter value to 'admin' and gain administrative privileges, even if they are not authorized to have such privileges.

To fix this vulnerability, the code should implement proper authentication and authorization mechanisms. This could involve using user tokens or session management to ensure that only authenticated and authorized users can access the '/admin' endpoint. Additionally, the code should validate the user's role against a secure and trusted source, such as a database, to prevent unauthorized privilege escalation.

Steps

  • Implement a proper authentication and authorization mechanism to control user roles and access privileges.
  • Avoid exposing user roles or sensitive information in the query parameters.
  • Use a secure session management mechanism to handle user sessions and tokens.
  • Ensure that only authenticated and authorized users can access the '/admin' route.
  • Consider implementing role-based access control (RBAC) to manage user roles and permissions.
  • Regularly review and update the role configuration to prevent any misconfigurations or vulnerabilities.

Compliant code

        import express from 'express';

const app = express();

// Implement proper authentication and authorization mechanism
app.use((req, res, next) => {
  // Secure session management mechanism to handle user sessions and tokens
  const userToken = req.headers.authorization;
  
  // Authenticate and authorize user based on userToken
  // Implement your authentication logic here

  // Example: Assuming userToken contains the role information
  if (userToken === 'admin') {
    req.userRole = 'admin';
  } else {
    req.userRole = 'standard';
  }

  next();
});

app.get('/admin', (req, res) => {
  // Ensure only authenticated and authorized users can access the '/admin' route
  if (req.userRole === 'admin') {
    res.send('Welcome, admin!');
  } else {
    res.send('Access denied!');
  }
});

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

The fixed code addresses the vulnerability by implementing proper authentication and authorization mechanisms.

First, the code imports the 'express' module and creates an instance of the express application.

Next, a middleware function is added using the app.use method. This middleware function is responsible for handling user authentication and authorization. It retrieves the user token from the request headers and performs the necessary authentication logic. In this example, it assumes that the user token contains role information.

If the user token is 'admin', the user role is set to 'admin'. Otherwise, it is set to 'standard'. This ensures that only authenticated users with the 'admin' role can access the '/admin' route.

The '/admin' route is defined using the app.get method. It checks the user role stored in the request object and sends the appropriate response. If the user role is 'admin', it sends a 'Welcome, admin!' message. Otherwise, it sends an 'Access denied!' message.

Finally, the application listens on port 3000 for incoming requests.

By implementing proper authentication and authorization mechanisms, the fixed code ensures that only authorized users can access sensitive routes and prevents privilege escalation vulnerabilities.

References