Improper authorization control for web services - TypeScript

Improper authorization control for web services - TypeScript

Need

Implementation of proper authorization control for web services

Context

  • Usage of TypeScript for statically typed JavaScript development
  • Usage of Express for building web applications and handling HTTP requests

Description

Non compliant code

        import express from 'express';

const app = express();

app.get('/api/confidential', (req, res) => {
  // Retrieve confidential information
  res.json({ data: 'Confidential information' });
});

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

The vulnerability in this code is that it lacks proper authorization control for the '/api/confidential' endpoint. This means that anyone who can access this endpoint will be able to retrieve confidential information without any authentication.

The code sets up an Express server and defines a route for the '/api/confidential' endpoint. When a GET request is made to this endpoint, the server responds with a JSON object containing the confidential information.

However, there is no mechanism in place to ensure that only authenticated users can access this endpoint. This means that anyone who knows the URL can retrieve the confidential information without any authentication or authorization checks.

To fix this vulnerability, the code should implement a validation mechanism such as session cookies or tokens to ensure that only authenticated users can access the '/api/confidential' endpoint. This would require users to provide some form of authentication credentials, such as a valid session cookie or token, before being granted access to the confidential information.

Steps

  • Implement an authentication mechanism to validate the user's identity before accessing the confidential information.
  • Use session cookies or tokens to authenticate users.
  • Create a middleware function to check the authentication status before allowing access to the '/api/confidential' endpoint.
  • If the user is not authenticated, return an appropriate error response or redirect them to the login page.
  • Store the user's authentication status in a secure manner, such as using encrypted session cookies or JWT tokens.
  • Ensure that the authentication mechanism is properly tested and validated to prevent any bypass or unauthorized access.

Compliant code

        import express, { Request, Response, NextFunction } from 'express';

const app = express();

// Middleware function to check authentication status
const authenticateUser = (req: Request, res: Response, next: NextFunction) => {
  // Check if user is authenticated
  const isAuthenticated = req.session?.authenticated;

  if (isAuthenticated) {
    // User is authenticated, allow access to the '/api/confidential' endpoint
    next();
  } else {
    // User is not authenticated, return an error response or redirect to login page
    res.status(401).json({ error: 'Unauthorized' });
  }
};

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.use(session({
  secret: 'your-secret-key',
  resave: false,
  saveUninitialized: true,
}));

app.get('/api/confidential', authenticateUser, (req, res) => {
  // Retrieve confidential information
  res.json({ data: 'Confidential information' });
});

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

The fixed code addresses the vulnerability by implementing an authorization control mechanism for web services.

The code uses the Express framework and starts by importing the necessary modules. It then creates an instance of the Express application.

The authenticateUser function is defined as a middleware function. This function takes in the request ( req), response ( res), and next middleware function ( next) as parameters. It checks if the user is authenticated by accessing the authenticated property in the session object ( req.session?.authenticated). If the user is authenticated, the function calls the next function to allow access to the protected endpoint. If the user is not authenticated, it returns a 401 Unauthorized error response.

The code sets up the necessary middleware for parsing JSON and URL-encoded data. It also configures the session middleware with a secret key.

The /api/confidential endpoint is defined with the app.get method. It takes in the authenticateUser middleware function as a parameter, ensuring that only authenticated users can access the endpoint. If the user is authenticated, the endpoint returns a JSON response with the confidential information.

Finally, the code starts the server and listens on port 3000.

Overall, the fixed code implements session-based authentication using session cookies. It checks if the user is authenticated before allowing access to the protected endpoint, thereby addressing the vulnerability of improper authorization control.

References