Weak credential policy - Password Change Limit - Java

Weak credential policy - Password Change Limit - Java

Need

Enforcement of a password change limit policy

Context

  • Usage of Java for building cross-platform applications
  • Usage of javax.servlet.http.* for handling HTTP requests and responses in Java Servlets
  • Usage of java.io.IOException for handling input/output errors in Java programming

Description

Non compliant code

        import javax.servlet.http.*;
import java.io.IOException;

public class ChangePasswordServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String oldPassword = request.getParameter("oldPassword");
        String newPassword = request.getParameter("newPassword");

        User user = Database.getUser(username);

        if (user != null && user.getPassword().equals(oldPassword)) {
            user.setPassword(newPassword);
            Database.updateUser(user);
            response.getWriter().write("Password successfully changed");
        } else {
            response.getWriter().write("Failed to change password");
        }
    }
}
        
        

In the above code, ChangePasswordServlet is a servlet that handles password change requests. It takes in three parameters from the client
- "username", "oldPassword", and "newPassword".

It first retrieves the user from the database using the username. If the user exists and the old password matches the current password of the user, it updates the password in the database with the new password.

The vulnerability here is that there is no limit on the number of password change requests a user can make in a day. An attacker could potentially exploit this by repeatedly changing the password and causing a denial of service or even potentially guessing the password if there are no other security measures in place like account lockouts or captcha.

Steps

  • Implement a password change limit policy
  • Track the number of password change requests made by a user
  • Set a maximum limit for password change requests within a specific time period
  • Enforce the password change limit by checking the number of requests made by a user
  • Return an error message or block the password change request if the limit is exceeded

Compliant code

        import javax.servlet.http.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class ChangePasswordServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private static final int MAX_PASSWORD_CHANGES_PER_DAY = 3;
    private Map passwordChangeCounter = new HashMap<>();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String oldPassword = request.getParameter("oldPassword");
        String newPassword = request.getParameter("newPassword");

        User user = Database.getUser(username);

        if (user != null && user.getPassword().equals(oldPassword)) {
            int passwordChanges = passwordChangeCounter.getOrDefault(username, 0);
            if (passwordChanges >= MAX_PASSWORD_CHANGES_PER_DAY) {
                response.getWriter().write("You have exceeded the maximum number of password changes per day.");
                return;
            }

            user.setPassword(newPassword);
            Database.updateUser(user);
            passwordChangeCounter.put(username, passwordChanges + 1);
            response.getWriter().write("Password successfully changed");
        } else {
            response.getWriter().write("Failed to change password");
        }
    }
}
        
        

The updated code now includes a password change limit policy. This policy is enforced by tracking the number of password change requests made by each user.

A HashMap named passwordChangeCounter is used to store the number of password change requests made by each user. The key is the username and the value is the number of password change requests.

When a password change request is made, the code first checks if the user exists and if the old password is correct. If these conditions are met, the code then checks the passwordChangeCounter to see how many password change requests the user has made.

If the user has made more than or equal to the maximum number of password changes allowed per day ( MAX_PASSWORD_CHANGES_PER_DAY), the code returns an error message and does not allow the password change.

If the user has not exceeded the limit, the password is changed, the user's password change count is incremented in the passwordChangeCounter, and a success message is returned.

This policy helps to prevent abuse of the password change feature and enhances the security of the application.

References