SonarQube提示需修改代码避免用用户可控数据构造路径的咨询
解决SonarQube路径构造风险提示
SonarQube提示的Change this code to not construct the path from user-controller data,是因为你直接用用户可控的type和version参数拼接文件名,存在路径注入/遍历风险——攻击者可以构造恶意参数(比如type=../secret/),让程序读写服务器上的敏感目录或文件。
核心修改思路
- 绝对禁止直接使用未校验的用户输入构造文件路径
- 对用户输入做严格校验或转义
- 固定文件存储目录,限制文件只能写入允许的范围
具体修改方案
方案1:校验+转义用户输入,固定存储目录
// 新增输入校验方法,只允许合法文件名字符 private boolean isValidParam(String param) { return param != null && param.matches("^[a-zA-Z0-9_-]+$"); } @GetMapping(value="", produces="application/zip") public ResponseEntity<FileSystemResource> gen(@RequestParam String version, @RequestParam String type) { // 先校验参数合法性,非法直接抛出异常 if (!isValidParam(version) || !isValidParam(type)) { throw new IllegalArgumentException("参数格式非法,仅允许字母、数字、下划线、短横线"); } List<File> files = service.getFiles(version, type); // 对参数做转义处理,替换掉所有非安全字符(双重保障) String safeType = type.replaceAll("[^a-zA-Z0-9_-]", "_"); String safeVersion = version.replaceAll("[^a-zA-Z0-9_-]", "_"); // 固定文件到系统临时目录(或你指定的合法存储目录) File tempDir = new File(System.getProperty("java.io.tmpdir")); // 使用File构造方法确保路径不会跳出指定目录 File zipFile = new File(tempDir, safeType + safeVersion + ".zip"); var result = zipping(files, zipFile.getAbsolutePath()); // 后续响应逻辑... return ResponseEntity.ok(new FileSystemResource(zipFile)); } public static File zipping(List<File> files, String filePath) { try (var fos = new FileOutputStream(filePath)) { // 补充你的压缩逻辑 } catch (IOException e) { throw new RuntimeException("生成压缩文件失败", e); } return new File(filePath); }
方案2:使用完全独立的文件名(推荐)
如果不需要用用户参数作为文件名的一部分,直接用UUID生成唯一文件名,彻底规避风险:
@GetMapping(value="", produces="application/zip") public ResponseEntity<FileSystemResource> gen(@RequestParam String version, @RequestParam String type) { List<File> files = service.getFiles(version, type); // 用UUID生成无意义的唯一文件名,完全脱离用户输入 String fileName = UUID.randomUUID().toString() + ".zip"; File tempDir = new File(System.getProperty("java.io.tmpdir")); File zipFile = new File(tempDir, fileName); var result = zipping(files, zipFile.getAbsolutePath()); // 如果需要关联用户的type和version,可以将对应关系存入数据库或日志 // 后续响应逻辑... return ResponseEntity.ok(new FileSystemResource(zipFile)); }
关键安全点说明
- 输入校验:通过正则限制参数只能包含安全字符,直接拦截恶意输入
- 固定目录:使用
new File(固定目录, 文件名)的方式,Java会自动处理路径中的../等遍历字符,确保文件始终在指定目录内 - 独立文件名:UUID生成的文件名完全不可预测,从根源避免路径注入风险
内容的提问来源于stack exchange,提问作者nick
相关产品推荐
相关产品推荐

