Skip to main content

Enabled default credentials

Need

Enforcement of strong, unique credentials for system access

Context

  • Usage of Java for building scalable and robust applications
  • Usage of javax.servlet.http.HttpServletRequest for handling HTTP requests in Java Servlets
  • Usage of HttpServletResponse for handling HTTP responses in Java Servlets
  • Usage of javax.servlet.ServletException for handling servlet exceptions in Java web applications
  • Handling IOException in Java Input/Output operations
  • Usage of javax.servlet.RequestDispatcher for dispatching requests to server-side resources

Description

Non compliant code

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

public class LoginServlet extends HttpServlet {

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

if(username.equals("admin") && password.equals("admin")) {
RequestDispatcher rd = request.getRequestDispatcher("welcome.jsp");
rd.forward(request, response);
} else {
response.sendRedirect("error.jsp");
}
}
}

The above code is a simple servlet that handles login requests. It checks if the username and password provided in the request match the default credentials, which are both set to "admin".

This is a clear example of a system with enabled default credentials vulnerability. The default credentials "admin" for both username and password are hard-coded into the system. These credentials are weak and can be easily guessed or discovered, posing a serious security threat.

An attacker could easily gain access to the system by using these default credentials, potentially leading to unauthorized access to sensitive data or functionality.

This vulnerability can be exploited through a simple brute force attack, where the attacker tries different combinations of commonly used usernames and passwords until they find a match. Because the credentials are set to "admin", a very common default credential, it wouldn't take long for an attacker to gain access.

In addition, the use of hard-coded credentials in the source code also means that every instance of this application will have the same default credentials, making it even easier for an attacker to gain unauthorized access.

This vulnerability could be mitigated by removing the hard-coded credentials and implementing a proper authentication system, where users are required to set their own unique, strong passwords.

Steps

  • Avoid using default credentials for authentication.
  • Implement a strong and secure authentication mechanism.
  • Use a secure password storage mechanism, such as hashing and salting.
  • Enforce password complexity requirements.
  • Implement account lockout mechanisms to prevent brute-force attacks.
  • Regularly update and patch the system to address any security vulnerabilities.
  • Perform security testing and code reviews to identify and fix any potential vulnerabilities.

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 LoginServlet extends HttpServlet {

private static final String SALT = "A random string for salt"; // This should be securely stored and retrieved

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

String hashedPassword = get_SHA_512_SecurePassword(password, SALT);

// Here, instead of comparing with hardcoded values, you should retrieve the hashed password from your database
// and compare it with the hashed input password
if(username.equals("admin") && hashedPassword.equals("hashed password from database")) {
RequestDispatcher rd = request.getRequestDispatcher("welcome.jsp");
rd.forward(request, response);
} else {
response.sendRedirect("error.jsp");
}
}

private static String get_SHA_512_SecurePassword(String passwordToHash, String salt){
String generatedPassword = null;
try {
MessageDigest md = MessageDigest.getInstance("SHA-512");
md.update(salt.getBytes("UTF-8"));
byte[] bytes = md.digest(passwordToHash.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for(int i=0; i< bytes.length ;i++){
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
}
generatedPassword = sb.toString();
}
catch (NoSuchAlgorithmException e){
e.printStackTrace();
}
catch (UnsupportedEncodingException e){
e.printStackTrace();
}
return generatedPassword;
}
}

The updated code now includes a secure password storage mechanism. Instead of storing and comparing passwords in plain text, we are now hashing the password using SHA-512 and a salt. The salt is a random string that is used to add additional randomness to the hashing process. This makes it more difficult for an attacker to use precomputed tables (rainbow tables) to crack the password.

The get_SHA_512_SecurePassword method is used to generate a hashed password. It takes the plain text password and the salt as input, and returns the hashed password.

In the doPost method, we now hash the input password and compare it with the hashed password retrieved from the database. This means that even if an attacker manages to get the hashed password, they will not be able to reverse-engineer it to get the original password.

Please note that this is a basic implementation and might not cover all security aspects. For a production system, consider using a well-tested authentication library or framework. Also, the salt should be securely stored and retrieved, and it should be unique for each user.

References