我使用Tomcat8/Java
我目前允许从服务器下载敏感的用户生成的Excel文件(在Java/POI中创建),方法是创建一个带有GUID的文件名,然后将其保存在一个公开可用的目录中,并提供该文件的链接。
第1阶段
用户选择各种参数,JSP将这些参数发送到Java文件
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();
}
第二阶段JSP然后在iFrame 中显示该文件
<iframe id="target_upload" name="target_upload" width="100%"
src="<%=fileName%>" height="100%"></iframe>
在我们的系统上进行的渗透测试的结果表明,我们应该从jsp文件中生成流中的文件,这样会更安全,因为它可以避免使用GUID,并且可以避免直接链接到绕过登录授权的文件。
然而,使用servlet似乎是更好的编码实践。例如实现一个简单的文件下载servlet。我正在考虑将文档保存在服务器上,由GUID标识,然后将该GUID传递给servlet。然而,这似乎违背了我提高安全性的初衷。
如果我实现一个简单的下载servlet(如所附链接),我如何在servlet中获得我创建的文件?
不是在阶段1中写入文件,然后在阶段2中读取该文件,您可以通过将工作簿写入HttpServletResponse.getOutputStream()来有效地将这两个步骤合并为1。
1。收集用户参数(假设这是在<form>
中完成的)并针对IFRAME发布它们。例如
<form action="reportservlet/MyReport.xls" method="POST" target="target_upload">
2。设置一个新的servlet +映射(*映射允许MyReport.xls部分是任何东西,包括你在提交表单时动态构建的东西)。
<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。在您的servlet中,类似于(忽略servlet中业务逻辑的"糟糕设计"…这只是示范)
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
}
. . 一些评论
- 我假设你正在为一组控制良好的用户开发,他们将a)使用IE和b)安装Excel -在IFRAME中瞄准Excel内容是一个非常糟糕的主意
- 绝对不要用JSP代替我建议的Servlet——使用JSP生成二进制数据只是一个"坏主意"。这在技术上是可行的,但是除非正确地构建JSP,否则很可能引入字符数据(很可能是难以看到的换行符和/或尾随空格),从而破坏XLS 。
我从实现一个简单的文件下载servlet中实现了@wen的答案
另外,我在如何拒绝web访问Tomcat目录
中使用@Ramesh PVK的建议删除了对文件保存目录的直接web访问。<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>