Skip to main content

Weak credential policy

Need

Implementation of a strong credential policy

Context

  • Usage of Java for building cross-platform applications
  • Usage of javax.servlet.http.HttpServletRequest for handling HTTP requests in Java Servlets
  • Usage of HttpServletResponse for handling HTTP responses in Java Servlet development
  • Usage of javax.servlet.ServletException for handling servlet exceptions
  • Handling of IOException in Java Input/Output operations
  • Usage of javax.servlet.http.HttpSession for managing user sessions in Java web applications

Description

Non compliant code

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

public class WeakCredentialPolicyServlet extends HttpServlet {

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

if (username != null && password != null) {
if (username.equals("admin") && password.equals("password")) {
HttpSession session = request.getSession();
session.setAttribute("username", username);
response.sendRedirect("success.jsp");
} else {
response.sendRedirect("failure.jsp");
}
}
}
}

The above code is an example of a servlet that implements a weak credential policy. The servlet handles POST requests, where it expects to receive a username and password parameter. It then checks if the username is "admin" and the password is "password". If the check passes, it creates a session for the user and redirects the user to a success page. Otherwise, it redirects the user to a failure page.

The vulnerability lies in the weak credential policy. The username and password are hardcoded into the application, and the password is a common and easily guessable one, "password". This makes the application susceptible to brute force attacks, where an attacker can try different combinations of usernames and passwords until they find one that works.

Furthermore, the application does not implement any form of password complexity requirements or account lockout mechanisms. This means that a user could choose a simple, easily guessable password, and an attacker could make unlimited attempts to guess a user's password. Both of these factors contribute to the weak credential policy.

To fix this vulnerability, the application should implement a strong credential policy. This could include requiring complex passwords, implementing account lockout mechanisms after a certain number of failed login attempts, and not hardcoding usernames and passwords into the application.

Steps

  • Implement a strong credential policy
  • Enforce password complexity requirements
  • Implement multi-factor authentication
  • Use secure password storage mechanisms
  • Implement account lockout mechanisms
  • Regularly update and patch the system

Compliant code

import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class StrongCredentialPolicyServlet extends HttpServlet {

private static final int MAX_ATTEMPTS = 5;
private static final Map<String, Integer> attempts = new HashMap<>();

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

if (username != null && password != null) {
if (isValidCredentials(username, password)) {
HttpSession session = request.getSession();
session.setAttribute("username", username);
response.sendRedirect("success.jsp");
} else {
Integer attempt = attempts.getOrDefault(username, 0);
attempts.put(username, attempt + 1);
if (attempt + 1 >= MAX_ATTEMPTS) {
response.sendRedirect("lockout.jsp");
} else {
response.sendRedirect("failure.jsp");
}
}
}
}

private boolean isValidCredentials(String username, String password) {
// Implement your own logic to validate the credentials
// This should include checking the password against a securely stored and hashed version of the password
// It should also include checking that the password meets complexity requirements
// And it should include multi-factor authentication
return false;
}

private String hashPassword(String password) {
MessageDigest md;
try {
md = MessageDigest.getInstance("SHA-256");
md.update(password.getBytes());
byte[] bytes = md.digest();
StringBuilder sb = new StringBuilder();
for (byte aByte : bytes) {
sb.append(Integer.toString((aByte & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}

The updated code now includes a strong credential policy.

  • The isValidCredentials method should be implemented to validate the credentials. This should include checking the password against a securely stored and hashed version of the password, checking that the password meets complexity requirements, and including multi-factor authentication.
  • The hashPassword method is used to securely hash the password using SHA-256. This is a one-way function, so the original password cannot be retrieved from the hashed version.
  • An account lockout mechanism has been implemented. If a user fails to log in MAX_ATTEMPTS times, they are redirected to a lockout page. This helps to prevent brute force attacks.
  • The system should be regularly updated and patched to ensure that it remains secure. This is not shown in the code, but is an important part of maintaining a secure system.

References