Lack of data validation - Responses - TypeScript

Lack of data validation - Responses - TypeScript

Need

Need for data validation and sanitization in response handling

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 userData: any;

app.post('/login', (req, res) => {
  // Simulating a login request
  const { username, password } = req.body;

  // Assuming the login is successful and we receive user data
  userData = {
    username,
    role: 'admin',
  };

  res.send('Login successful');
});

app.get('/profile', (req, res) => {
  // Simulating a profile request
  res.send(userData);
});

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

The vulnerability in this code is the lack of data validation in the response data. In the /login route, when a user successfully logs in, the server receives the username and sets the userData variable to an object containing the username and a role.

In the /profile route, the server sends the userData object as a response. However, there is no validation performed on the userData object before sending it. This means that if an attacker modifies the userData object to contain invalid or malicious data, the server will still send it in subsequent requests without any validation.

This vulnerability can compromise the integrity of the information processed by the server. An attacker could manipulate the userData object to gain unauthorized access or perform malicious actions on the server.

To mitigate this vulnerability, it is recommended to validate the data before sending it in subsequent requests. The server should perform thorough validation on the userData object, ensuring that the data is in the expected format and meets the necessary criteria. This can help prevent the server from processing and acting upon invalid or malicious data.

Steps

  • Implement data validation for the username and password fields in the '/login' route handler.
  • Validate the user data received from the '/login' route before storing it in the 'userData' variable.
  • Implement data validation for the 'userData' object before sending it in the '/profile' route handler.

Compliant code

        import express from 'express';
import { body, validationResult } from 'express-validator';

const app = express();

let userData: { username: string, role: string } | undefined;

app.post('/login', [
  body('username').notEmpty().isString(),
  body('password').notEmpty().isString(),
], (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }

  const { username, password } = req.body;

  // Assuming the login is successful and we receive user data
  userData = {
    username,
    role: 'admin',
  };

  res.send('Login successful');
});

app.get('/profile', (req, res) => {
  if (!userData) {
    return res.status(404).send('User data not found');
  }

  res.send(userData);
});

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

The fixed code addresses the vulnerability by implementing data validation on the server-side using the express-validator library.

In the code, we import the necessary modules from the express and express-validator libraries. We create an instance of the express application and define the routes for login and profile.

For the '/login' route, we use the express-validator's body function to define validation rules for the 'username' and 'password' fields. The notEmpty rule ensures that the fields are not empty, and the isString rule checks that the values are of type string. If any validation errors occur, we return a 400 status code with the error messages.

Assuming the login is successful, we store the user data (username and role) in the userData variable.

For the '/profile' route, we check if the userData variable is defined. If it is not, we return a 404 status code with the message 'User data not found'. Otherwise, we send the userData as a response.

By implementing data validation on the server-side, we ensure that only valid data is accepted and processed by the server. This helps to prevent the compromise of information and maintains the integrity of the requests processed by the server.

References