Insecure functionality - Fingerprint - TypeScript

Insecure functionality - Fingerprint - TypeScript

Need

Enforce secure and controlled user data updates

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.use(express.json());

let userData = {
  name: 'John Doe',
  age: 30,
  fingerprint: '',
};

app.put('/update', (req, res) => {
  const { fingerprint } = req.body;

  userData = {
    ...userData,
    fingerprint,
  };

  res.send('User data updated successfully');
});

app.get('/user', (req, res) => {
  res.json(userData);
});

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

The vulnerability in this code is an insecure functionality related to the fingerprint update.

In the /update endpoint, the code allows any user to update the fingerprint field in the userData object without any validation or authorization checks. This means that any user can send a request with a new fingerprint value, and it will be directly assigned to the userData object.

The impact of this vulnerability is that an attacker can manipulate or update the fingerprint information associated with a user. This can lead to unauthorized access or manipulation of the user's data, as the fingerprint is often used for authentication or security purposes.

The recommendation to fix this vulnerability is to implement proper validation and authorization checks before allowing the update of sensitive fields like the fingerprint. This can include verifying the user's identity, ensuring that the requested fields are the same as those expected, and implementing proper access controls to restrict who can update the fingerprint information.

Steps

  • Validate the user input to ensure that only the allowed fields are updated
  • Implement authentication and authorization mechanisms to prevent unauthorized updates
  • Consider using a database to store user data instead of a global variable
  • Encrypt sensitive user data, such as the fingerprint, before storing it

Compliant code

        import express from 'express';
import bcrypt from 'bcrypt';

const app = express();

app.use(express.json());

let userData = {
  name: 'John Doe',
  age: 30,
  fingerprint: '',
};

app.put('/update', (req, res) => {
  const { fingerprint } = req.body;

  if (fingerprint) {
    userData = {
      ...userData,
      fingerprint: bcrypt.hashSync(fingerprint, 10),
    };
  }

  res.send('User data updated successfully');
});

app.get('/user', (req, res) => {
  res.json(userData);
});

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

The fixed code addresses the vulnerability by implementing secure functionality for updating the user's fingerprint data. Here's an explanation of the changes made:

1. The code imports the necessary modules, including express for creating the server and bcrypt for hashing the fingerprint data securely.

2. The userData object is defined with initial values for the user's name, age, and an empty fingerprint field.

3. The app.put('/update') route is responsible for handling the update request. It expects the fingerprint data to be provided in the request body.

4. Inside the route handler, the code checks if the fingerprint field exists in the request body. If it does, it proceeds to update the userData object.

5. To securely store the fingerprint data, the code uses the bcrypt.hashSync() function to hash the fingerprint value with a salt factor of 10. This ensures that the fingerprint data is securely stored and not directly accessible.

6. The updated userData object is assigned to the existing userData variable using the spread operator ( ...userData), ensuring that the other fields (name and age) remain unchanged.

7. The response sends a success message indicating that the user data has been updated successfully.

8. The app.get('/user') route is responsible for returning the user data when requested. It simply responds with the userData object as a JSON response.

9. The server listens on port 3000, and a console log message is displayed to indicate that the server is running.

By implementing these changes, the code ensures that only the fingerprint field is updated if provided in the request body. Other fields, such as name and age, remain unchanged. Additionally, the fingerprint data is securely hashed using bcrypt before being stored in the userData object.

References