基础
- 通过用户输入,后端接收到参数直接拼接到指定路径下读取用户的文件名,看似正常,但是用户输入的参数不可控制,黑客将非法的特殊字符作为文件名的一部分,操作到其他路径下,甚至是跳转到服务器敏感目录,读取敏感的配置文件,例如服务器的密码文件,程序数据库,redis等核心配置文件
问题
@GetMapping("/path_traversal/vul")
public String getImage(String filepath) throws IOException {
return getImgBase64(filepath);
}
private String getImgBase64(String imgFile) throws IOException {
logger.info("Working directory: " + System.getProperty("user.dir"));
logger.info("File path: " + imgFile);
File f = new File(imgFile);
if (f.exists() && !f.isDirectory()) {
byte[] data = Files.readAllBytes(Paths.get(imgFile));
return new String(Base64.encodeBase64(data));
} else {
return "File doesn't exist or is not a file.";
}
}
解决
-
这里对目录穿越的…进行了过滤,避免了目录穿越。只不过这里一个用作图片读取的api也可以读取项目任意文件倒也可以说是算一个小漏洞。
@GetMapping("/path_traversal/sec") public String getImageSec(String filepath) throws IOException { if (SecurityUtil.pathFilter(filepath) == null) { logger.info("Illegal file path: " + filepath); return "Bad boy. Illegal file path."; } return getImgBase64(filepath); } /** * Filter file path to prevent path traversal vulns. * * @param filepath file path * @return illegal file path return null */ public static String pathFilter(String filepath) { String temp = filepath; // use while to sovle multi urlencode while (temp.indexOf('%') != -1) { try { temp = URLDecoder.decode(temp, "utf-8"); } catch (UnsupportedEncodingException e) { logger.info("Unsupported encoding exception: " + filepath); return null; } catch (Exception e) { logger.info(e.toString()); return null; } }
关键词
1 new FileInputStream( path
2 new FileOutputStream( path
3 new File( path
4 RandomAccessFile fp = new RandomAccessFile(fname,"r");
5mkdirs
6 getOriginalFilename
7 entry.getName(
...