Sonar检测到用户可指定路径文件读取漏洞,对应Java代码如何修复?
漏洞根因
该告警属于路径遍历漏洞,你的代码存在两处风险点:
- 仅在本地文件读取时用
FilenameUtils.getName()做了路径净化,但是ClassLoader.getResource()直接传入未校验的原始configFileName参数,攻击者可构造带../的payload读取classpath范围内的任意敏感文件 - 未限制可读取的文件范围,即便提取了纯文件名,也可能被利用读取当前工作目录下的未授权文件
修复方案
1. 统一净化输入参数
所有用到文件名的位置统一使用净化后的纯文件名,禁止直接使用原始入参:
- 调用
FilenameUtils.getName()剥离所有路径前缀,仅保留最终文件名 - 增加文件名格式校验,根据业务场景限制允许的文件名后缀、字符范围,比如仅允许
.properties/.yml/.xml等配置类后缀,禁止特殊字符
2. 增加路径白名单校验
读取文件后调用getCanonicalPath()获取文件的规范路径(可解析相对路径、软链接避免绕过),校验路径是否在预设的白名单目录内,禁止访问白名单外的任意路径。
修复后代码示例
public static final String getFilePath(String configFileName) throws FileNotFoundException, IOException { // 统一净化入参,仅保留纯文件名 String safeFileName = FilenameUtils.getName(configFileName); // 文件名格式合法性校验,可根据业务调整规则 if (!safeFileName.matches("^[a-zA-Z0-9_\\-]+\\.(properties|yml|yaml|xml)$")) { logger.error("Invalid config file name: {}", configFileName); throw new IllegalArgumentException("Illegal config file name"); } File configFile = new File(safeFileName); if (configFile.exists()) { // 校验文件路径是否在允许的白名单目录内,示例限制为当前工作目录下的config文件夹 String allowedDir = new File("./config").getCanonicalPath(); String actualPath = configFile.getCanonicalPath(); if (!actualPath.startsWith(allowedDir)) { logger.error("Access to file outside allowed directory: {}", actualPath); throw new SecurityException("Unauthorized file access"); } return actualPath; } // 传入净化后的文件名,而非原始入参 URL url = ConfigHelper.class.getClassLoader().getResource(safeFileName); if (url != null) { return url.getPath(); } logger.error("Failed to find the file on classpath: {}", configFileName); return null; }
内容的提问来源于stack exchange,提问作者AbhiRam
相关产品推荐
相关产品推荐

