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, consider the following strategies:
-
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.
-
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.
-
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.
-
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.
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_.-]", "");
}
}