Password change without identity check - PHP

Password change without identity check - PHP

Need

Enforce strong identity verification for password changes

Context

  • Usage of PHP 7.0 for server-side scripting and web development
  • Usage of Request for making HTTP requests
  • Usage of Auth for user authentication and authorization
  • Usage of Hash for data encryption and password hashing

Description

Non compliant code

        public function changePassword(Request $request) {
    $user = Auth::user();
    $new_password = $request->input('new_password');

    $user->password = Hash::make($new_password);
    $user->save();
}
        
        

This code is an example of a password change function in a Laravel application. This function is vulnerable because it allows a user to change their password without verifying their identity.

The changePassword function first gets the authenticated user with Auth::user(). Then, it retrieves the new password from the request input with $request->input('new_password').

The problem here is that there is no check for the user's old password or any other form of identity verification. This means that if a user's session is hijacked, the attacker can change the password without knowing the original password.

Furthermore, there are no checks for password complexity, length, or similarity to the old password. This means that users can set weak passwords, or even passwords that are the same as their old password.

This vulnerability can lead to unauthorized access to user accounts, data breaches, and other security issues.

Steps

  • Add an additional input field for the current password in the request.
  • Before changing the password, verify the current password provided by the user with the one stored in the database.
  • If the current password does not match, return an error message indicating that the current password is incorrect.
  • Only if the current password is correct, proceed to update the password with the new one provided by the user.
  • Consider adding additional identity verification mechanisms such as two-factor authentication or security questions.

Compliant code

        public function changePassword(Request $request) {
    $user = Auth::user();
    $current_password = $request->input('current_password');
    $new_password = $request->input('new_password');

    if (!Hash::check($current_password, $user->password)) {
        return response()->json(['error' => 'Current password is incorrect'], 400);
    }

    $user->password = Hash::make($new_password);
    $user->save();

    return response()->json(['success' => 'Password changed successfully'], 200);
}
        
        

The updated code now includes an additional input field for the current password. This is used to verify the identity of the user before allowing them to change their password.

The Hash::check function is used to compare the current password provided by the user with the one stored in the database. This function takes two arguments: the plain-text password to check and the hashed password to check against. If the two passwords do not match, the function returns false.

If the Hash::check function returns false, the code returns a JSON response with a 400 status code and an error message indicating that the current password is incorrect.

If the Hash::check function returns true, the code proceeds to update the password with the new one provided by the user. The new password is hashed using the Hash::make function before it is stored in the database.

Finally, a JSON response with a 200 status code and a success message is returned to indicate that the password has been changed successfully.

This code provides a basic level of identity verification by requiring the user to provide their current password before they can change it. However, for additional security, consider implementing more robust identity verification mechanisms such as two-factor authentication or security questions.

References