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