JAVA开发常见安全问题:任意文件上传
·
专栏链接
一、数据的校验
二、认证与授权
三、Cookie与会话管理
四、错误处理
五、日志安全
六、未验证的重定向
数据的校验:任意文件上传
漏洞描述:
允许用户上传任意文件可能会让攻击者注入危险内容或恶意代码,并在服务器上运行。由于文件上传功能实现代码没有严格限制用户上传的文件后缀以及文件类型,导致允许攻击者向某个可通过 Web 访问的目录上传任意动态脚本文件(JSP、PHP 等),并能够将这些文件传递给 web 服务器进行解释,就可以在远程服务器上执行该脚本。
检测方法:
检查服务端代码中有没有对可上传的文件类型进行限制,比如采用白名单方式。禁止被上传危险文件类型,比如:jsp、php、html、js。
不合规的代码示例:
public ActionForward uploadFile(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)
{
PlanFlowForm planFlowForm = (PlanFlowForm) form;
String city =SessionInfoUtil.getStaffSessBean(request.getSession()).getCityCode();
String filePath = request.getRealPath(UPLOAD_PATH);
String newFileName = null;
String filename = null;
try{
InputStream in = planFlowForm.getUpFile().getInputStream();
filename = planFlowForm.getUpFile().getFileName();
newFileName = PlanFlowModule.consFileName(city,filename);
try{
BufferedReader is= new BufferedReader(new InputStreamReader(in));
StringBuffer out = new StringBuffer();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream bos = new FileOutputStream(filePath+ "/" +newFileName);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = in.read(buffer, 0, 8192)) !=-1){
bos.write(buffer, 0, bytesRead);
}
bos.close();
in.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
catch(Exception e)
{
log.error(e);
}
request.setAttribute("filename", newFileName);
request.setAttribute("showname", filename);
return mapping.findForward("filewin");
}
合规的代码示例:
public static final Pattern p = Pattern.compile("(\\.txt|\\.xls|\\.xlsx|\\.docx|\\.pdf|
\\.gif|\\.bmp|\\.jpg|\\.png)");
public static boolean fileNameCheck(String str){
str = str.toLowerCase();
Matcher matcher = p.matcher(str);
if(matcher.find()){
return true;
}else{
return false;
}
}
public ActionForward uploadFile(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response){
PlanFlowForm planFlowForm = (PlanFlowForm) form;
String city = SessionInfoUtil.getStaffSessBean(request.getSession()). getCityCode();
String filePath = request.getRealPath(UPLOAD_PATH);
String newFileName = null;
String filename = null;
try{
filename=planFlowForm.getUpFile().getFileName();
//判断文件名的后缀是否在白名单中,如果不存在,则跳转到错误页面
if(!fileNameCheck(filename)){
request.setAttribute("filename", newFileName);
request.setAttribute("showname", filename);
return mapping.findForward("filewin");
}
InputStream in = planFlowForm.getUpFile().getInputStream();
newFileName = PlanFlowModule.consFileName(city,filename);
try{
BufferedReader is= new BufferedReader(new InputStreamReader(in));
StringBuffer out = new StringBuffer();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream bos = new FileOutputStream(filePath+ "/" +newFileName);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = in.read(buffer, 0, 8192)) !=-1)
{
bos.write(buffer, 0, bytesRead);
}
bos.close();
in.close();
}catch(Exception e){
e.printStackTrace();
}
}catch(Exception e){
log.error(e);
}
request.setAttribute("filename", newFileName);
request.setAttribute("showname", filename);
return mapping.findForward("filewin");
}
合规说明:
采用白名单的方式检测上传文件的后缀名,防止攻击者上传恶意脚本文件。
更多推荐



所有评论(0)