Skip to main content

Directory listing

Need

Prevention of unauthorized access to directory listings

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.*;

public class DirectoryListingServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String path = getServletContext().getRealPath("/");
File directory = new File(path);
String[] files = directory.list();

PrintWriter out = response.getWriter();

for(String file : files) {
out.println(file);
}
}
}

The above Java Servlet code is vulnerable to directory listing. The doGet method is used to handle HTTP GET requests. When a GET request is received, it obtains the real path of the server's directory by calling getServletContext().getRealPath("/"). Then, it creates a File object with this path, effectively pointing to the server's root directory.

The list() method is then called on this File object, which returns an array of strings naming the files and directories in the directory denoted by this abstract pathname.

The server then writes these file and directory names to the HTTP response using a PrintWriter, which is obtained from the HttpServletResponse object. This means that anyone who sends a GET request to this servlet can see the names of all files and directories on the server's root directory.

This is a severe security vulnerability as it exposes the structure of the server's file system to potential attackers, who can use this information to craft more targeted attacks.

Steps

  • Disable directory listing
  • Implement access controls
  • Sanitize user input

Compliant code

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

public class DirectoryListingServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String path = getServletContext().getRealPath("/");
File directory = new File(path);
if(directory.isDirectory()){
String[] files = directory.list();
if(files != null){
PrintWriter out = response.getWriter();
for(String file : files) {
if(!file.startsWith(".")){
out.println(file);
}
}
}
} else {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
}
}
}

The code above is a revised version of the original servlet that was vulnerable to directory listing. The vulnerability was that it allowed anyone to view the contents of the server's directories, which could potentially expose sensitive information.

The revised code includes a check to see if the requested path is a directory. If it is not, the servlet responds with a 403 Forbidden error, which prevents the client from viewing the contents of non-directory paths.

Additionally, the revised code includes a check to see if the directory's list of files is not null before attempting to print the file names. This prevents a potential NullPointerException.

Finally, the revised code includes a check to see if a file name starts with a period ('.'). Files that start with a period are typically hidden files in Unix-based systems, and these files often contain sensitive information. By not printing the names of these files, the servlet further reduces the risk of exposing sensitive information.

This revised code effectively mitigates the directory listing vulnerability by implementing access controls and sanitizing user input.

References