文件操作 - 路径穿越
漏洞案例
漏洞描述
安全编码
目录遍历, 应用系统在处理下载文件时未对文件进行过滤,系统后台程序程序中如果不能正确地过滤客户端提交的../和./之类的目录跳转符,攻击者可以通过输入../进行目录跳转,从而下载、删除任意文件。
【必须】避免路径拼接 1. 文件目录避免外部参数拼接。 2. 保存文件目录建议后台写死并对文件名进行校验(字符类型、长度)。 3. 建议文件保存时,将文件名替换为随机字符串。 如因业务需要不能满足1.2.3的要求,需判断请求文件名和文件路径参数中是否存在../或..\(windows), 如存在应判定路径非法并拒绝请求。
运行
漏洞代码
// 文件路径没做限制,通过../递归下载任意文件 // PoC:/Traversal/download?filename=../../../../../../../etc/passwd @GetMapping("/download") public String download(String filename, HttpServletRequest request, HttpServletResponse response) { String filePath = System.getProperty("user.dir") + "/logs/" + filename; try { File file = new File(filePath); InputStream is = new BufferedInputStream(new FileInputStream(file)); byte[] buffer = new byte[is.available()]; fis.read(buffer); fis.close(); response.reset(); response.addHeader("Content-Disposition", "attachment;filename=" + filename); response.addHeader("Content-Length", "" + file.length()); OutputStream toClient = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/octet-stream"); toClient.write(buffer); toClient.flush(); toClient.close(); return "下载文件成功:" + filePath;
运行
安全代码 - 过滤
// 过滤..和/ public static boolean check_traversal(String content) { return content.contains("..") || content.contains("/"); }
安全代码 - id参数化
// 对文件名做映射生成id值,通过参数化下载文件可以有效防止遍历问题 // 需要注意:控制用户权限,避免通过遍历下载文件(越权)