Lack of data validation - Path Traversal - Java

Lack of data validation - Path Traversal - Java

Need

Implementation of robust data validation and sanitization mechanisms

Context

  • Usage of Java for building cross-platform applications
  • Usage of javax.servlet.http.HttpServletRequest for handling HTTP requests in Java Servlets
  • Usage of java.io.FileInputStream for reading data from a file
  • Usage of javax.servlet.ServletException for handling servlet-related exceptions
  • Handling IOException for Input/Output operations in Java
  • Usage of HttpServletResponse for handling HTTP responses in Java Servlets

Description

Non compliant code

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

public class VulnerableServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String filename = request.getParameter("filename");
        FileInputStream fis = new FileInputStream("/uploads/" + filename);
        // Rest of the code...
    }
}
        
        

In the above code, the doGet method of VulnerableServlet class is taking a filename as input from the request parameter without any validation or sanitization. This filename is then used to create a FileInputStream object.

This is a classic example of a Path Traversal vulnerability because the application uses the filename directly from the user input to access a file. If an attacker sends a specially crafted request with a parameter like filename=../../../etc/passwd, the application will attempt to read a file from a directory that is outside of the intended directory (in this case, it will attempt to read the system's password file).

This lack of data validation allows an attacker to read any file on the system that the application has access to, leading to a potential information disclosure vulnerability. It could also potentially lead to remote code execution if the attacker can read a file that they can also write to.

Steps

  • Implement proper input validation and sanitization.
  • Do not directly use user input to construct file paths.
  • Use a whitelist approach to validate and sanitize the input.
  • Ensure that the user input does not contain any special characters or sequences that could be used for path traversal.
  • Consider using a library or framework that provides built-in protection against path traversal attacks.
  • Restrict access to sensitive directories and files.
  • Implement access controls and permissions to prevent unauthorized access to files.
  • Regularly update and patch the software to fix any known vulnerabilities.

Compliant code

        import javax.servlet.http.*;
import java.io.*;
import java.nio.file.Paths;
import java.nio.file.Path;

public class SecureServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String filename = request.getParameter("filename");

        // Validate the filename using a whitelist approach
        if (!filename.matches("[a-zA-Z0-9_\\\\.]+")) {
            throw new ServletException("Invalid filename.");
        }

        // Construct the path safely
        Path path = Paths.get("/uploads", filename).normalize();

        // Check if the path is still within the allowed directory after normalization
        if (!path.startsWith("/uploads")) {
            throw new ServletException("Path traversal attempt detected.");
        }

        FileInputStream fis = new FileInputStream(path.toString());
        // Rest of the code...
    }
}
        
        

The updated code now includes input validation and sanitization to prevent path traversal attacks.

Firstly, the filename obtained from the user input is validated using a whitelist approach. The regular expression [a-zA-Z0-9_\\\\.]+ ensures that the filename only contains alphanumeric characters, underscores, and periods. If the filename contains any other characters, a ServletException is thrown.

Next, the file path is constructed using the Paths.get() method, which safely constructs a path by joining the given inputs. The normalize() method is then called on the path to resolve any "." or ".." sequences that could be used for path traversal.

After normalization, a check is performed to ensure that the path still starts with "/uploads". If it doesn't, this indicates a path traversal attempt, and a ServletException is thrown.

This approach ensures that the user input does not contain any special characters or sequences that could be used for path traversal, effectively preventing path traversal attacks.

In addition to this, it is recommended to implement access controls and permissions to prevent unauthorized access to files, restrict access to sensitive directories and files, and regularly update and patch the software to fix any known vulnerabilities.

References