安全地允许从服务器下载用户生成的文件



我使用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
}
. .

一些评论

  1. 我假设你正在为一组控制良好的用户开发,他们将a)使用IE和b)安装Excel -在IFRAME中瞄准Excel内容是一个非常糟糕的主意
  2. 绝对不要用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>

相关内容

  • 没有找到相关文章

最新更新