jeecgboot/JeecgBoot · error · JeecgBootException
非法业务路径,禁止访问上传目录之外的路径: ${bizPath}
Error message
非法业务路径,禁止访问上传目录之外的路径: ${bizPath} What it means
A CWE-22 path-traversal guard inside uploadLocal: both the configured upload root (uploadpath) and the target folder (uploadpath/bizPath) are canonicalized via getCanonicalFile(), and if the target path does not start with the upload root, the request is rejected. This catches ../ escapes, absolute-path tricks, and symlinked targets that resolve outside the upload directory.
Source
Thrown at jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysCommentServiceImpl.java:361
* @return
*/
private String uploadLocal(MultipartFile mf, String bizPath) {
try {
// 文件安全校验,防止上传漏洞文件
SsrfFileTypeFilter.checkUploadFileType(mf, bizPath);
} catch (Exception e) {
throw new JeecgBootException(e);
}
try {
String ctxPath = uploadpath;
String fileName = null;
//update-begin---author:liusq ---date:2026-03-30 for:【issues/9427】修复uploadLocal bizPath路径遍历漏洞(CWE-22)-----------
// 路径遍历校验:规范化后确保目标目录在uploadpath内
File uploadDir = new File(ctxPath).getCanonicalFile();
File file = new File(ctxPath + 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/9427】修复uploadLocal bizPath路径遍历漏洞(CWE-22)-----------
if (!file.exists()) {
file.mkdirs();// 创建文件根目录
}
String orgName = mf.getOriginalFilename();// 获取文件名
orgName = CommonUtils.getFileName(orgName);
if (orgName.indexOf(".") != -1) {
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
} else {
fileName = orgName + "_" + System.currentTimeMillis();
}
String savePath = file.getPath() + File.separator + fileName;
File savefile = new File(savePath);
FileCopyUtils.copy(mf.getBytes(), savefile);
String dbpath = null;
if (oConvertUtils.isNotEmpty(bizPath)) {
dbpath = bizPath + File.separator + fileName;View on GitHub (pinned to 96fb33f5ec)
Solutions
- Ensure bizPath is a simple relative subfolder (e.g. 'temp', 'avatar', 'dict').
- Strip any '../', leading '/', and backslashes before calling uploadLocal.
- Never pass raw user input as bizPath; resolve it from a server-side allowlist.
Example fix
// before
String bizPath = request.getParameter("biz"); // attacker: ../../etc
savePath = uploadLocal(file, bizPath); // throws 非法业务路径...
// after
String bizPath = ALLOWED_BIZ.getOrDefault(request.getParameter("biz"), "upload");
// ALLOWED_BIZ is a fixed map of safe folder names
savePath = uploadLocal(file, bizPath); Defensive patterns
Strategy: validation
Validate before calling
// Normalize bizPath and confirm it stays within uploadpath BEFORE writing.
File root = new File(uploadpath).getCanonicalFile();
File target = new File(uploadpath + File.separator + bizPath).getCanonicalFile();
if (!target.toPath().startsWith(root.toPath())) {
throw new IllegalArgumentException("非法业务路径: " + bizPath);
} Type guard
public boolean isBizPathSafe(String bizPath, String uploadpath) {
try {
File root = new File(uploadpath).getCanonicalFile();
File target = new File(uploadpath + File.separator + bizPath + File.separator).getCanonicalFile();
return target.toPath().startsWith(root.toPath());
} catch (IOException e) { return false; }
} Try / catch
try {
return uploadLocal(file, bizPath);
} catch (JeecgBootException e) {
if (e.getMessage() != null && e.getMessage().startsWith("非法业务路径")) {
log.warn("路径遍历拦截: bizPath={}", bizPath);
return Result.error("非法的存储路径");
}
throw e;
} Prevention
- Resolve bizPath from a server-side allowlist of folder names, never from raw input.
- Strip ../, leading /, and backslashes from any user-supplied path segment.
- Always use getCanonicalFile() comparisons when constraining a path to a root.
- Alert on repeated path-traversal attempts — they may indicate probing.
When it happens
Trigger: bizPath like '../../etc', '/etc', '..\\..\\windows'; absolute paths; symlinked folders resolving outside uploadpath; bizPath crafted to escape via OS-specific separators.
Common situations: Client-supplied bizPath not sanitized; legacy callers passing user-controlled paths directly; OS differences in canonicalization; misconfigured uploadpath differing between nodes.
Related errors
- Illegal access to path outside of base directory.
- 非法业务路径,禁止访问上传目录之外的路径: ${bizPath}
- 非法存储路径,路径包含遍历字符: {storePath}
- 文件路径包含非法字符
- 非法文件路径,禁止访问上传目录之外的文件:
AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14).
Data as JSON: /api/errors/e6e744201234f086.
Report an issue: GitHub.