Skip to main content

Business information leak - Personal Information

Need

Protection of personal information from unauthorized access or leakage

Context

  • Usage of Java for building robust and scalable applications
  • Usage of javax.servlet for handling HTTP requests and responses in Java web applications
  • Usage of javax.servlet.http for handling HTTP requests and responses in Java Servlets

Description

Non compliant code

import javax.servlet.*;
import javax.servlet.http.*;

public class UserInfoServlet extends HttpServlet {

private static final String USER_ID = "123456789";
private static final String USER_PHONE = "1234567890";

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1>User Information</h1>");
out.println("<p>User ID: " + USER_ID + "</p>");
out.println("<p>User Phone: " + USER_PHONE + "</p>");
out.println("</body></html>");
}
}

The above code is a simple Servlet that handles GET requests and responds with a webpage containing user information. The Servlet is vulnerable because it stores sensitive user information such as the user's ID number and phone number directly in the source code.

These values are stored as static final variables at the class level, making them accessible throughout the class and its instances. In the doGet() method, these values are directly embedded into the HTML response that is sent back to the client.

This is a serious security vulnerability as it exposes sensitive user information to anyone who can access the source code. Furthermore, this approach does not allow for dynamic handling of user data, as the values are hardcoded and cannot be changed without modifying the source code.

This vulnerability can lead to information disclosure, which could be used for identity theft or other malicious activities. It also violates principles of good software design, such as data encapsulation and separation of concerns.

The sensitive data should be stored securely, such as in a database, and retrieved only when necessary. It should also be obfuscated or encrypted to prevent unauthorized access. Additionally, the application should implement proper access controls to ensure that only authorized users can access the data.

Steps

  • Do not store sensitive information such as real ID numbers and phone numbers in the source code.
  • Implement a secure data storage mechanism such as a database or encrypted file system to store sensitive information.
  • Retrieve the sensitive information from the secure storage mechanism when needed, instead of hardcoding it in the source code.
  • Ensure that access to the sensitive information is properly authenticated and authorized.
  • Implement proper access controls to restrict who can access the sensitive information.
  • Regularly review and update the access controls and security measures to protect the sensitive information.
  • Consider implementing additional security measures such as data encryption and secure communication protocols to further protect the sensitive information.

Compliant code

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

public class UserInfoServlet extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1>User Information</h1>");

// Connect to the database
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");

// Execute SQL query
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM Users WHERE id = 'some_id'");

// Extract data from result set
while(rs.next()){
//Retrieve by column name
String id = rs.getString("id");
String phone = rs.getString("phone");

//Display values
out.println("<p>User ID: " + id + "</p>");
out.println("<p>User Phone: " + phone + "</p>");
}
rs.close();
} catch(SQLException se){
//Handle errors for JDBC
se.printStackTrace();
} catch(Exception e){
//Handle errors for Class.forName
e.printStackTrace();
} finally {
//finally block used to close resources
try{
if(stmt!=null)
stmt.close();
} catch(SQLException se2){
} // nothing we can do
try{
if(con!=null)
con.close();
} catch(SQLException se){
se.printStackTrace();
} //end finally try
} //end try
out.println("</body></html>");
}
}

The updated code no longer stores sensitive user information directly in the source code. Instead, it retrieves this information from a secure database when needed.

The doGet method now establishes a connection to a MySQL database using the DriverManager.getConnection method. It then creates a Statement object and executes a SQL query to retrieve the user's ID and phone number from the Users table in the database.

The sensitive user information is then displayed in the response to the client. Note that the database connection, username, and password are placeholders and should be replaced with your actual database connection details.

The database connection, statement, and result set objects are properly closed in the finally block to prevent resource leaks.

This approach ensures that sensitive user information is not exposed in the source code, and access to this information is properly authenticated and authorized through the database.

Remember to implement proper access controls on the database to restrict who can access the sensitive user information. Regularly review and update these access controls and other security measures to protect the sensitive information.

Consider implementing additional security measures such as data encryption and secure communication protocols to further protect the sensitive information.

References