Fortify检测到Path Manipulation漏洞,现有修复方案无效求解决
Path Manipulation漏洞修复思路(java.io.tmpdir场景)
问题场景与代码
当前代码如下,Fortify检测出Path Manipulation漏洞:
private static final String ALLOWABLE_CHARS= "[\\/a-zA-Z0-9_\-~:]+"; public static void generateZipFile(MultipartFile file) { File tempFile; try { String path = System.getProperty("java.io.tmpdir"); // 拒绝包含非允许字符的文件路径 if (path.matches(ALLOWABLE_CHARS)) { tempFile = Files.createTempFile(Paths.get(path).normalize(), "prefix", "suffix").toFile(); //剩余代码 . . .
Fortify告警原因:认为攻击者可控制System.getProperty("java.io.tmpdir")的返回值,进而通过Paths.get(path)访问或修改受保护文件,调用链为getProperty(return) -> path -> Paths.get(path)。
你尝试的路径规范化、字符正则校验两种方式未解决问题,以下是可行的修复思路:
修复思路
直接使用JDK内置安全API创建临时文件
放弃手动指定java.io.tmpdir,直接调用Files.createTempFile("prefix", "suffix")。这个方法会自动使用系统默认临时目录,且由JDK内部处理路径安全,从根源避免路径操纵风险。修改后代码示例:public static void generateZipFile(MultipartFile file) { File tempFile; try { tempFile = Files.createTempFile("prefix", "suffix").toFile(); // 剩余业务代码 . . .临时目录白名单校验
字符校验无法防范合法字符组成的恶意路径(比如java.io.tmpdir被篡改指向敏感目录)。可以预先定义允许的临时目录白名单,将获取到的路径标准化后与白名单对比,只有匹配才继续执行:// 定义跨平台允许的临时目录白名单 private static final Set<String> ALLOWED_TEMP_DIRS = Set.of( "/tmp", "/var/tmp", // Linux/Unix类系统 "C:\\Temp", "C:\\Windows\\Temp" // Windows系统(注意转义反斜杠) ); public static void generateZipFile(MultipartFile file) { File tempFile; try { String path = System.getProperty("java.io.tmpdir"); // 标准化路径,消除末尾斜杠、相对路径等差异 String normalizedPath = Paths.get(path).normalize().toString(); // 校验是否在白名单内 if (ALLOWED_TEMP_DIRS.contains(normalizedPath)) { tempFile = Files.createTempFile(Paths.get(normalizedPath), "prefix", "suffix").toFile(); // 剩余业务代码 . . .强制路径范围校验
将获取到的临时目录转为绝对路径,创建文件后校验最终路径是否落在该目录范围内,确保不会跳出预期路径:public static void generateZipFile(MultipartFile file) { File tempFile; try { String path = System.getProperty("java.io.tmpdir"); Path baseTempDir = Paths.get(path).normalize().toAbsolutePath(); // 创建临时文件 tempFile = Files.createTempFile(baseTempDir, "prefix", "suffix").toFile(); // 校验生成的文件路径是否在基准目录下 Path tempFilePath = tempFile.toPath().normalize(); if (!tempFilePath.startsWith(baseTempDir)) { throw new SecurityException("临时文件路径超出允许范围"); } // 剩余业务代码 . . .
内容的提问来源于stack exchange,提问作者RagaSGNur
相关产品推荐
相关产品推荐

