Reflected File Download

ID

java.reflected_file_download

Severity

high

Resource

Injection

Language

Java

Tags

CWE:79, NIST.SP.800-53, OWASP:2021:A3, PCI-DSS:6.5.1

Description

Improper neutralization of external input that leads to reflected file download ('RFD').

Rationale

Reflected file download vulnerabilities (a variation of cross-site scripting classified under CWE-79) occur when user input is reflected in the contents or headers of a downloadable file without proper sanitization.

Attackers can exploit this to inject malicious scripts or content, tricking users into downloading and executing harmful files. This can occur when a web application reflects unsanitized user input back in the HTTP response, particularly in content-disposition or content-type headers involved in file downloads.

Consider the following Java servlet example, which demonstrates a potential vulnerability:

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

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

        // Potential vulnerability: reflecting user input in headers
        response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");

        // Assume file content is being processed and sent as a response
        response.getWriter().println("File content of: " + filename);
    }
}

In the example above, the filename is taken directly from user input and used in the content-disposition header, making this setup susceptible to reflected file download attacks if the input is not properly sanitized.

Remediation

To remediate reflected file download vulnerabilities in Java applications, consider the following strategies:

  1. Validate and Sanitize User Input: Always validate and sanitize user inputs before using them in HTTP headers or anywhere in the response. Implement whitelist validation strategies to limit inputs to allowed patterns or values.

    public class SecureFileDownloadServlet extends HttpServlet {
       protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           String filename = request.getParameter("filename");
    
           // Validate and sanitize the filename
           if (filename != null && filename.matches("^[a-zA-Z0-9_.-]+$")) {
               response.setHeader("Content-Disposition", "attachment; filename=\"" + sanitizeFilename(filename) + "\"");
               response.getWriter().println("Secure file content of: " + sanitizeFilename(filename));
           } else {
               // Handle invalid input scenario
               response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid file name.");
           }
       }
    
       private String sanitizeFilename(String filename) {
           return filename.replaceAll("[^a-zA-Z0-9_.-]", "");
       }
    }
  2. Encode Output Appropriately: Use appropriate output encoding for HTTP headers (like URL encoding) to ensure that no executable scripts are injected in the header values.

  3. Use Strong Content-Type and Content-Disposition Directives: When dynamically setting these headers, ensure that the content is aligned explicitly with the expected content type and that potentially dangerous content is not executed.

  4. Perform Regular Security Testing: Employ comprehensive security testing, including static and dynamic analysis, to detect potential vulnerabilities and ensure that all input and output handling follows best practices.

By following these practices, reflected file download vulnerabilities can be mitigated, enhancing the security of Java web applications.

Configuration

The rule has the following configurable parameters:

  • sources, that indicates the source kinds to check.

  • neutralizations, that indicates the neutralization kinds to check.