簡體   English   中英

安全地允許用戶生成的文件從服務器下載

[英]Securely allow user-generated files to be downloaded from server

我使用Tomcat8 / Java

我目前允許通過使用GUID創建文件名,然后將其保存在公共目錄中,並提供該文件的鏈接,來從服務器下載敏感的用戶生成的Excel文件(以Java / POI創建)。

階段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中獲取創建的文件?

通過將工作簿寫入HttpServletResponse.getOutputStream(),而不是在階段1中寫入文件並在階段2中讀取該文件,可以有效地將兩個步驟折疊為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的答案

此外,我刪除了使用@Ramesh PVK在如何拒絕對Tomcat目錄的Web訪問中的建議對文件保存目錄的直接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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM