Skip to main content

Password change without identity check

Need

Enforce strong identity verification for password changes

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.post('/change-password', (req, res) => {
const { newPassword } = req.body;
// Update password logic here
res.send('Password changed successfully');
});

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

The vulnerability in this code is that it allows a user to change their password without any identity verification mechanism. The code only checks for the presence of a new password in the request body and updates the password without any further checks.

This means that an attacker who gains unauthorized access to a user's session or account can easily change the password without needing to provide the current password or any other form of identity verification. This can lead to a complete takeover of the user's account, allowing the attacker to impersonate the legitimate user and perform malicious actions.

To fix this vulnerability, the code should implement proper identity verification mechanisms before allowing a password change. This could include requesting the current password from the user and comparing it with the stored password to ensure that the user is the legitimate account owner. Additionally, a second authentication mechanism, such as a one-time password (OTP) or email verification, should be used to further confirm the identity of the user requesting the password change.

Steps

  • Implement a mechanism to verify the user's current password before allowing a password change.
  • Add an additional authentication mechanism, such as a second factor authentication, to ensure the password change is performed by the account owner.

Compliant code

import express from 'express';

const app = express();

app.post('/change-password', (req, res) => {
const { currentPassword, newPassword } = req.body;

// Verify the user's current password
if (!verifyCurrentPassword(currentPassword)) {
return res.status(401).send('Invalid current password');
}

// Perform additional authentication mechanism, such as second factor authentication
if (!performAdditionalAuthentication()) {
return res.status(401).send('Additional authentication failed');
}

// Update password logic here
updatePassword(newPassword);

res.send('Password changed successfully');
});

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

function verifyCurrentPassword(currentPassword: string): boolean {
// Implement logic to verify the current password
// Return true if the current password is valid, false otherwise
}

function performAdditionalAuthentication(): boolean {
// Implement logic for additional authentication mechanism
// Return true if the additional authentication is successful, false otherwise
}

function updatePassword(newPassword: string): void {
// Implement logic to update the password
}

The fixed code addresses the vulnerability by implementing several measures to ensure the security of the password change process.

  1. The code uses the Express framework to handle HTTP requests and responses.

  2. The /change-password endpoint is defined as a POST request, indicating that it is used for changing passwords.

  3. The request body is expected to contain the currentPassword and newPassword fields.

  4. The code starts by verifying the user's current password using the verifyCurrentPassword function. If the current password is invalid, a 401 Unauthorized response is sent back to the client.

  5. Next, the code performs an additional authentication mechanism, such as a second factor authentication, using the performAdditionalAuthentication function. If the additional authentication fails, a 401 Unauthorized response is sent back to the client.

  6. If both the current password verification and additional authentication are successful, the code proceeds to update the password using the updatePassword function.

  7. Finally, a success message is sent back to the client with a 200 OK response.

  8. The code also includes the necessary implementation for the verifyCurrentPassword, performAdditionalAuthentication, and updatePassword functions. These functions should be implemented with appropriate logic to verify the current password, perform additional authentication, and update the password, respectively.

By implementing these measures, the code ensures that the current password is required and that an additional authentication mechanism is enforced before allowing a password change. This significantly reduces the risk of unauthorized access to user accounts.

References