Skip to main content

Lack of data validation - OTP

Need

Implementation of proper data validation for OTP (One-Time Password) values

Context

  • Usage of TypeScript for type-checking and compiling JavaScript code
  • Usage of Express for building web applications and APIs

Description

Non compliant code

import express from 'express';

const app = express();

app.post('/createAccount', (req, res) => {
const { tokenCode } = req.body;

// No validation of the tokenCode parameter

// Perform account creation process without validating the token

res.send('Account created successfully');
});

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

The vulnerability in this code is the lack of data validation for the tokenCode parameter in the /createAccount route. The code does not perform any checks or validation on the value of tokenCode before proceeding with the account creation process.

This means that any value can be sent in the tokenCode parameter, including random or invalid values. This allows an attacker to perform the account creation process without knowing the actual generated token.

Without proper validation, an attacker can potentially bypass the intended security measures and create an account without having the valid token. This can lead to unauthorized access or abuse of the system.

To address this vulnerability, the code should implement server-side validation to ensure that the token sent by the user is the one generated for the request. Additionally, it should validate that the token generated is used only once, preventing multiple attempts with the same token.

By implementing these validation checks, the code can ensure the integrity and security of the account creation process.

Steps

  • Validate on the server side that the token sent by the user is the one generated for the request.
  • Validate that the token generated is used only once.

Compliant code

import express from 'express';

const app = express();

// Store the generated tokens in a Set
const usedTokens = new Set<string>();

app.post('/createAccount', (req, res) => {
const { tokenCode } = req.body;

// Validate that the token sent by the user is the one generated for the request
if (!validateToken(tokenCode)) {
return res.status(400).send('Invalid token');
}

// Validate that the token generated is used only once
if (usedTokens.has(tokenCode)) {
return res.status(400).send('Token already used');
}

// Add the token to the usedTokens Set
usedTokens.add(tokenCode);

// Perform account creation process

res.send('Account created successfully');
});

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

// Function to validate the token
function validateToken(tokenCode: string): boolean {
// Add your validation logic here
// Return true if the token is valid, false otherwise
return true;
}

The fixed code addresses the lack of data validation in the tokenCode parameter by implementing server-side validation and ensuring that the token generated is used only once. Here's an explanation of the changes made:

  1. A Set called usedTokens is created to store the generated tokens. This allows us to keep track of the tokens that have already been used.

  2. In the /createAccount route handler, the tokenCode is extracted from the request body.

  3. The validateToken function is called to validate the token sent by the user. This function should contain the actual validation logic specific to your application. If the token is not valid, a 400 response with the message "Invalid token" is sent back to the client.

  4. The usedTokens Set is checked to ensure that the token has not been used before. If the token is found in the usedTokens Set, a 400 response with the message "Token already used" is sent back to the client.

  5. If the token is valid and has not been used before, it is added to the usedTokens Set.

  6. Finally, the account creation process is performed and a success message is sent back to the client.

Note: The validateToken function is a placeholder and needs to be implemented with your specific token validation logic. It should return true if the token is valid and false otherwise.

Overall, these changes ensure that the token sent by the user is validated on the server side and that each token can only be used once, mitigating the vulnerability of using random values in multiple attempts.

References