文件操作 - 任意文件上传
漏洞案例
漏洞描述
安全编码
文件上传漏洞,是指用户上传了一个可执行的脚本文件(如jsp\php\asp),并通过此脚本文件获得了执行服务器端命令的能力。常见场景是web服务器允许用户上传图片或者普通文本文件保存,这种漏洞属于低成本高杀伤力
【必须】文件类型限制 必须在服务器端采用白名单方式对上传或下载的文件类型、大小进行严格的限制。仅允许业务所需文件类型上传,避免上传.jsp、.jspx、.html、.exe等危险文件。 【建议】其他 对上传的文件回显相对路径或者不显示路径。 设置目录权限限制,禁止上传目录的执行权限。 建议使用OSS静态存储服务器来存储用户上传的文件
漏洞代码
// 允许上传任意文件导致的安全风险 public String singleFileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) { try { byte[] bytes = file.getBytes(); Path dir = Paths.get(UPLOADED_FOLDER); Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename()); Files.write(path, bytes); redirectAttributes.addFlashAttribute("message","上传文件成功:" + path + ""); } catch (Exception e) { return e.toString(); } return "redirect:upload_status"; }
安全代码 - 白名单
// 对上传文件后缀名做白名单处理 public String singleFileUploadSafe(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) { try { byte[] bytes = file.getBytes(); String fileName = file.getOriginalFilename(); Path dir = Paths.get(UPLOADED_FOLDER); Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename()); // 获取文件后缀名 String Suffix = fileName.substring(fileName.lastIndexOf(".")); String[] SuffixSafe = {".jpg", ".png", ".jpeg", ".gif", ".bmp", ".ico"}; boolean flag = false; for (String s : SuffixSafe) { if (Suffix.toLowerCase().equals(s)) { flag = true; break; } } if (!flag) { return "只允许上传图片,[.jpg, .png, .jpeg, .gif, .bmp, .ico]"; }