简体   繁体   中英

Securely allow user-generated files to be downloaded from server

I use Tomcat8/Java

I currently allow sensitive user-generated Excel files (created in Java/POI) to be downloaded from the server by creating a file name with a GUID and then saving it in a publicly available directory, and providing the link for this file.

Stage 1

The User selects various parameters, which the JSP sends to a Java file

String fileName = "excelFiles/"
                + myReports
                        .createExcel(listCompanyDetails);

public static String createExcel(List listCompanyDetails) {
        String fileName = "MyFile"+UUID.randomUUID() + ".xls";
        String fileFullPath="\..."+fileName;
        FileInputStream inputStream = new FileInputStream(new File(APPCodeTable.templateExcelFile));
        Workbook wb=new HSSFWorkbook(inputStream);
        FileOutputStream out = new FileOutputStream(fileFullPath);
        wb.write(out);
        out.close();
}

Stage 2

The JSP then displays the file in an iFrame

<iframe id="target_upload" name="target_upload" width="100%"
src="<%=fileName%>" height="100%"></iframe>

The results of a Penetration Test done on our system said that we should instead produce the file in a stream from a jsp file, and this would be more secure, as it would avoid the use of GUID's, and would avoid having a direct link to the file which would bypass the login authorization.

It seems however that it is better coding practice to use a servlet. For instance Implementing a simple file download servlet .

I was considering saving the document on the server, identified by a GUID, and then passing this GUID to the servlet. However this seems to defeat my original intentions of improving security.

If I implement a simple download servlet (as in the attached link), how can I get my created file inside that servlet?

instead of writing to a file in Stage 1 and reading that file in Stage 2, you can effectively collapse the two steps into 1 by writing the Workbook to HttpServletResponse.getOutputStream().

1. collect user parameters (assuming this is done in a <form> ) and POST them targeting the IFRAME. eg

 <form action="reportservlet/MyReport.xls" method="POST" target="target_upload">

2. setup a new servlet + mapping (the * mapping allows the MyReport.xls part to be anything..including something you build on the fly when submitting the form).

<servlet>
    <servlet-name>ReportServlet</servlet-name>
    <servlet-class>foo.ReportServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ReportServlet</servlet-name>
    <url-pattern>/reportservlet/*</url-pattern>
</servlet-mapping>

3. in your servlet, something like (ignore "bad design" of business logic in a servlet..this is demonstrative only)

public void doPost(HttpServletRequest req, HttpServletResponse rsp) throws ServletException {
    // all the security stuff and stuff to produce List listCompanyDetails
    FileInputStream inputStream = new FileInputStream(new File(APPCodeTable.templateExcelFile));
    Workbook wb=new HSSFWorkbook(inputStream);
    rsp.setContentType("application/vnd.ms-excel");
    wb.write(rsp.getOutputStream()); // this is the key...write directly to the request output vs. a temp file
}

some commentary..

  1. i'm assuming you're developing for a well-controlled set of users who will be a) using IE and b) have Excel installed - targeting excel content in an IFRAME is a pretty bad idea
  2. definitely don't use a JSP in place of my suggested Servlet - using JSP to produce binary data is just a "bad idea". Its technically possible, but unless you structure your JSP correctly, you're likely to introduce character data (most likely a hard-to-see newline and/or trailing space) that will corrupt the XLS

I implemented @wen's answer from Implementing a simple file download servlet

Additionally I removed direct web access to the directory where the files were saved using @Ramesh PVK's suggestion in How to deny web access to a Tomcat directory

<security-constraint>
  <web-resource-collection>
    <web-resource-name >precluded methods</web-resource-name>
    <url-pattern >/excelFiles/*</url-pattern>
    </web-resource-collection>
    <auth-constraint/>
</security-constraint>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM