Skip to main content

Lack of data validation - Type confusion

Need

Implementation of robust data validation and type checking mechanisms

Context

  • Usage of Java for building robust and scalable applications
  • Usage of javax.servlet for building Java web applications with Servlet technology
  • Usage of java.io for input and output operations in Java

Description

Non compliant code

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

public class VulnerableServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String number = req.getParameter("number");
int parsedNumber = Integer.parseInt(number); // vulnerable point
resp.getWriter().write("Parsed Number: " + parsedNumber);
}
}

The above Java Servlet is vulnerable to type confusion due to lack of proper data validation. This servlet accepts a GET request and expects a parameter named number.

The vulnerability lies in the following line of code:

int parsedNumber = Integer.parseInt(number); // vulnerable point

Here, the number parameter, which is a string, is directly parsed to an integer using Integer.parseInt(). This function can interpret hexadecimal numbers if they are in the format of 0x.... Hence, if a user provides an input like 0xff, it will be accepted and interpreted as 255 by the server, even though the server expects only decimal numbers.

This could lead to unexpected behavior and potential security risks, as the server is not correctly validating the data type and format of the user input.

Steps

  • Implement proper data validation on the server-side to ensure that the input is of the expected type.
  • Use appropriate data types and parsing methods to handle the input data.
  • Avoid relying solely on client-side validation as it can be bypassed.
  • Consider using a whitelist approach to validate the input, allowing only specific characters or patterns.
  • Sanitize the input by removing any non-numeric characters before parsing.
  • Handle exceptions properly to prevent the application from crashing or leaking sensitive information.

Compliant code

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

public class SecureServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String number = req.getParameter("number");
if (isValidNumber(number)) {
int parsedNumber = Integer.parseInt(number);
resp.getWriter().write("Parsed Number: " + parsedNumber);
} else {
resp.getWriter().write("Invalid input");
}
}

private boolean isValidNumber(String number) {
return number != null && number.matches("\\\\d+");
}
}

The above code fixes the vulnerability by adding a server-side validation method isValidNumber(String number). This method checks if the input string is a valid number by using a regular expression that matches only numeric characters (0-9).

The doGet method now uses this validation method to check the input before parsing it. If the input is not a valid number, it responds with "Invalid input" instead of trying to parse it. This prevents type confusion as the server will no longer attempt to parse non-numeric values.

This solution also follows the principle of whitelisting, as it only allows specific characters (0-9) in the input. It also sanitizes the input by implicitly removing any non-numeric characters, as these will cause the validation method to return false.

Finally, this solution handles exceptions properly by not allowing invalid input to reach the point where it could cause an exception. This prevents the application from crashing due to an unhandled exception, and also prevents any sensitive information from being leaked in an error message.

References