新手,在下面的int中,它将文件作为参数并将其连接到目录字符串,然后查找文件并使用流获取并将文件提供给浏览器进行下载。该代码容易受到目录遍历的影响,并且不确定如何加强代码以抵消此问题。
<%
if(request.getParameter("file")!=null)
{
String context = request.getContextPath();
int BUFSIZE = 4096;
String filePath;
filePath = request.getParameter("file");
File file = new File(getServletContext().getRealPath("/") +context);
file = new File(file.getParent()+"/documents/"+filePath);
int length = 0;
ServletOutputStream outStream = response.getOutputStream();
//response.setContentType("text/html");
response.setContentLength((int)file.length());
String fileName = (new File(filePath)).getName();
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
//response.setHeader("Content-Disposition", "attachment; filename=\"" +new Random().nextInt(10000)+ "\"");
byte[] byteBuffer = new byte[BUFSIZE];
DataInputStream in = new DataInputStream(new FileInputStream(file));
while ((in != null) && ((length = in.read(byteBuffer)) != -1))
{
outStream.write(byteBuffer,0,length);
}
in.close();
outStream.close();
}
else
{
}
%>
答案 0 :(得分:0)
问题包括使用不可信文件名创建outputFile。 验证文件名将解决您的PathTraversal。
补救示例:
if (validateFileName(request.getParameter("file")));
filePath = request.getParameter("file");
else
// Error
//....
//.....
boolean validateFilename(String fileName)
{
// This represents the format /myapp/temp/<filename>
String goodPattern = "/myapp/temp/(\\w|\\s|\\.|-|){1,20}";
File file = new File (fileName);
Pattern p = Pattern.compile(goodPattern);
Matcher m = p.matcher(file.getCanonicalPath());
if (!m.matches())
{
return false;
}
return true;
}
请参阅: