java文件上传审计

审计点简述

 

 审计文件名-审计后缀名-审计文件内容-

审计点--文件名称

1.文件名存在目录穿越漏洞

漏洞原因:开发者直接将用户输入的文件名拼接在路径上进行查找

漏洞修复:开发者直接指定一个路径,不信任用户的路径(添加一个时间戳)

文件名直接拼接产生漏洞:/ab/c+file_name --> /a/b/c/1.jpg --> /a/b/c/../../../1.jpg

2.文件名存在xss

漏洞原因:主要在文件上传后,返回体显示文件 + A+ 上传成功字样可能会有xss

"文件名" +A+ "上传成功" -->  文件<img scr=1 onerror=alert(1)>上传成功

审计点--后缀判断

1.取后缀的方式

indexof(".") --> 1.jpg.jsp --> .jpg.jsp

lastindexof(".") --> 1.jsp.jpg --> .jpg

2.判断后缀与mime文件格式的方式(大小写转化,黑百名单)
tolowercase --> 1.jsp --> ".jsp"

equals(suffix)   #suffix可以是黑名单可以是白名单

审计点--文件格式

BufferedImage image=ImageIO.read(file);

image.getWidth() ---- image.getHeight()

  JPEG FFD8FF

  PNG 89504E47

  GIF 47494638

  TIFF 49492A00  tif

文件上传修复方式

1. 存储路径不完全可控 --> 不要将文件名称拼接或者直接返回

2.后缀名和格式类型白名单判断

3.不解析直接下载 -->取消预览

4.统一资源服务器-->不过要注意ssrf

两种找到上传点的方法

1.全局搜索关键字 例如函数关键字或者中文注释关键字

2.通过抓包看路径后全局搜索

 

packege qccp.springvc.sec;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
@Controller
@RequestMapping("file")
public class FileUploadController{
  @GetMapping("/")
  public String index(){
    return "/WEB-INF/jsp/upload.jsp";
  }
  @RequestMapping(value="/uploadimgsec",method=RequestMethod.POST)
  @ResponseBody
  public String uploadFilesec(@RequestParam("file") MultipartFile file){
  if(!file.isEmpty()){
    try{
      String rootPath="../webapps/ROOT/upload";
      File dir = new File(rootPath+File.separator+"img");
      if(!dir.exists())
        dir.mkdirs();
      String fileName=file.getOriginalFilename();
      String contentType=file.getContentType();
      String Suffix=fileName.substring (fileNmae.lastIndexOf("."));    #通过fileName.substring(fileName.lastIndexOf(".")方式获取最后的后缀不会被.jpg.jsp绕过
      String picwhite[] = {".jpg",".jpeg",".png",".gif",".bmp"};  
      String whitetype[]={"image/gif","image/jpeg","image/jpg","image/png"};    #通过contenttype白名单过滤
      Boolean picFlag=false;
      Boolean typeFlag=false;
      for(String white_suffix:picwhite){
        if{Suffix.toLowerCase().equals(white_suffix)){
          picFlag=ture;
          break;
          }
      }
      for(String type:whitetype){
        if(contentType.toLowerCase().equals(type)){
          typeFlag=true;
          break;
        }
      }
      if(!picFlag){
        return "file type not allowed!";
      }
      if(!typeFlag){
        return "file type not allowed";
      }
      System.out.println(Interger.toHexString((int)new Date().getTime()));
      Date date=new Date();
      SimpleDateFormat dateFormat=new SimpleDateFormat("yyyyMMddhhmmss");
      String newfilename = dateFormat.format(date)+Interger.toHexStirng((int)new Date().getTime())+Suffix;    #将文件名重新打包避免上传文件被恶意利用
      File serverFile=new File(dir.getAbsolutePath()+File.separator+newfilename);
      file.transferTo(serverFile);
      return "upload file successfully="+new fileanme;
  }catch(Exception e){
    return "upload file fail" + file.getOriginalFilename() + "->" + e.getMessage();
   }
  }
}

 

posted @ 2023-04-05 22:09  lisenMiller  阅读(233)  评论(0)    收藏  举报