jeecgboot/JeecgBoot · critical · JeecgBootException
非法业务路径,禁止访问上传目录之外的路径: ${bizPath}
Error message
非法业务路径,禁止访问上传目录之外的路径: ${bizPath} What it means
A second path-traversal guard (CWE-22) in CommonUtils.uploadLocal, covering the MultipartFile-based upload flow (vs the byte[] flow in error 14). It canonicalizes both the uploadpath root and the uploadpath+bizPath target via getCanonicalFile(), then asserts the target starts with the upload dir. If a bizPath escapes the upload directory after canonicalization, it throws JeecgBootException. Added for issues/9428. It also runs SsrfFileTypeFilter.checkUploadFileType to block disallowed file types.
Source
Thrown at jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/CommonUtils.java:180
}
/**
* 本地文件上传
* @param mf 文件
* @param bizPath 自定义路径
* @return
*/
public static String uploadLocal(MultipartFile mf,String bizPath,String uploadpath){
try {
// 文件安全校验,防止上传漏洞文件
SsrfFileTypeFilter.checkUploadFileType(mf, bizPath);
String fileName = null;
//update-begin---author:liusq ---date:2026-03-30 for:【issues/9428】修复uploadLocal bizPath路径遍历漏洞(CWE-22)-----------
// 路径遍历校验:规范化后确保目标目录在uploadpath内
File uploadDir = new File(uploadpath).getCanonicalFile();
File file = new File(uploadpath + File.separator + bizPath + File.separator).getCanonicalFile();
if (!file.toPath().startsWith(uploadDir.toPath())) {
throw new JeecgBootException("非法业务路径,禁止访问上传目录之外的路径: " + bizPath);
}
//update-end---author:liusq ---date:2026-03-30 for:【issues/9428】修复uploadLocal bizPath路径遍历漏洞(CWE-22)-----------
if (!file.exists()) {
// 创建文件根目录
file.mkdirs();
}
// 获取文件名
String orgName = mf.getOriginalFilename();
// 无中文情况下进行转码
if (orgName != null && !CommonUtils.ifContainChinese(orgName)) {
orgName = new String(orgName.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
}
orgName = CommonUtils.getFileName(orgName);
if(orgName.indexOf(SymbolConstant.SPOT)!=-1){
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
}else{
fileName = orgName+ "_" + System.currentTimeMillis();
}View on GitHub (pinned to 96fb33f5ec)
Solutions
- Validate and sanitize bizPath server-side before reaching uploadLocal: reject '..' and absolute paths.
- Use a fixed allow-list of subdirectories for bizPath.
- Ensure the configured uploadpath is a real, non-symlinked absolute directory.
- Run SsrfFileTypeFilter checks earlier and fail fast with a clear message.
Example fix
// before — bizPath built from unvalidated input
String bizPath = request.getParameter("path"); // "../secret"
// after — validate against allow-list
String bizPath = sanitizeBizPath(request.getParameter("path"));
if (bizPath == null) throw new IllegalArgumentException("invalid bizPath"); Defensive patterns
Strategy: validation
Validate before calling
// Validate bizPath against the upload dir before uploadLocal
public static void safeUploadLocal(MultipartFile mf, String bizPath, String uploadpath) {
File dir = new File(uploadpath + File.separator + bizPath).getCanonicalFile();
File root = new File(uploadpath).getCanonicalFile();
if (!dir.toPath().startsWith(root.toPath()))
throw new IllegalArgumentException("bizPath escapes upload dir");
CommonUtils.uploadLocal(mf, bizPath, uploadpath);
} Type guard
public static boolean bizPathWithinRoot(String bizPath, String uploadpath) throws IOException {
Path root = Paths.get(uploadpath).toRealPath();
Path target = Paths.get(uploadpath, bizPath).toAbsolutePath().normalize();
return target.startsWith(root);
} Try / catch
try {
CommonUtils.uploadLocal(mf, bizPath, uploadpath);
} catch (JeecgBootException e) {
response.sendError(400, "Illegal upload path");
} Prevention
- Sanitize bizPath server-side; reject '..' and absolute paths.
- Use a fixed allow-list of upload subdirectories.
- Ensure uploadpath is a real, non-symlinked absolute directory.
- Combine file-type filtering with path validation.
When it happens
Trigger: A multipart upload request whose bizPath parameter resolves (after symlink resolution and normalization via getCanonicalFile) to a location outside the configured uploadpath. Attacker-controlled bizPath with traversal sequences or symlink-laden base paths.
Common situations: Security testing of the upload endpoint; a frontend bug concatenating paths with '..'; a shared upload root where a symlink points outside; misconfigured uploadpath that itself contains traversal segments.
Related errors
- Illegal access to path outside of base directory.
- 非法业务路径,禁止访问上传目录之外的路径: ${bizPath}
- 请注意,将要排序的列字段不存在:${column}
- 未获取到用户
- 非法存储路径,路径包含遍历字符: {storePath}
AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14).
Data as JSON: /api/errors/714ad5fd2572d4d5.
Report an issue: GitHub.