2016-08-17 4 views
0

Я использую Tomcat8/JavaБезопасно позволяют пользователю генерируемые файлы, которые будут загружены с сервера

Я в настоящее время позволяют чувствительных сгенерированных пользователем файлов Excel (созданных в Java/POI), которые будут загружены с сервера путем создания имени файла с GUID, а затем сохраните его в общедоступном каталоге и предоставив ссылку для этого файла.

Стадия 1

Пользователь выбирает различные параметры, которые СПЯ посылает в файл 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(); 
} 

Стадия 2

СПЯ затем отображает файл в плавающем фрейме

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

Результаты теста на проникновение, проведенного в нашей системе, говорят о том, что мы должны вместо этого генерировать файл в потоке из файла jsp, и это было бы более безопасным, поскольку это позволило бы избежать использования GUID и избежать прямого ссылку на файл, который будет обходить авторизацию входа.

Кажется, что лучше использовать кодировку для использования сервлета. Например, Implementing a simple file download servlet.

Я рассматривал возможность сохранения документа на сервере, идентифицированного с помощью GUID, и передачи этого GUID на сервлет. Однако это, похоже, превзошло мои первоначальные намерения улучшить безопасность.

Если я реализую простой сервлет загрузки (как в прилагаемой ссылке), как я могу получить свой созданный файл внутри этого сервлета?

+0

просто потоковое это через сервлет казалось бы, не для решения какой-либо проблемы безопасности - тем более, что статические res Наши сервисы через Tomcat уже обслуживаются сервлетом (Catalina DefaultServlet). Таким образом, ответ на этот вопрос требует лучшего понимания того, что на самом деле обнаружение безопасности (по сравнению с предлагаемым решением поиска) –

+0

Я немного изменил свой вопрос в отношении проблем безопасности – gordon613

+0

«однако мне все равно нужно сохранить документ на сервере» .... это утверждение не обязательно верно (или рассуждения о том, почему это было бы правдой, не ясно). Если вы на самом деле генерировали XLSX «на лету» (т. Е. Вызванный HttpServletRequest), вместо того, чтобы записывать Workbook в FileOutputStream, вы должны записать его в OutputStream HttpServletResponse. например new Workbook(). write (httpServletResponse.getOutputStream()) Для этого есть немного больше, чем это, но если этот подход кажется жизнеспособным, я напишу подробности в форме ответа –

ответ

0

вместо записи в файл на первом этапе и чтения этого файла на этапе 2, вы можете эффективно свернуть два шага в 1, записав книгу в HttpServletResponse.getOutputStream().

1. собирать пользовательские параметры (при условии, что это делается в <form>) и POST их таргетинга на IFRAME. например

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

2. установка новый сервлет + отображение (* отображение позволяет MyReport.xls часть быть что-то вы строите на лету при отправке формы anything..including).

<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..this показателен только)

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 - таргетинг на excel-контент в IFRAME - довольно плохая идея
  2. определенно не используют JSP вместо моего предложенного сервлета - использование JSP для создания двоичных данных - всего лишь «плохая идея».Технически это возможно, но если вы правильно структурируете свой JSP, вы, скорее всего, представите характерные данные (скорее всего, труднодоступную новость и/или конечное пространство), которые могут повредить XLS
+0

Спасибо. Просто вернулся из отпуска - извините за задержку в ответе ... Как мне передать мой список ListCompanyDetails на сервлет doPost? – gordon613

0

Я реализовал @ ответ вэнь от Implementing a simple file download servlet

Кроме того, я удален прямой веб-доступ к каталогу, в котором были сохранены файлы, используя предложение @Ramesh ПВК в 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>