jeecgboot/JeecgBoot · critical · SecurityException
Illegal access to path outside of base directory.
Error message
Illegal access to path outside of base directory.
What it means
This is a path-traversal (CWE-22) security guard in the local-upload path of CommonUtils.uploadOnlineImage. After running SsrfFileTypeFilter.checkPathTraversal on the bizPath, it normalizes both the basePath root and the resolved target directory and asserts targetDir.startsWith(root). If a crafted bizPath (e.g. ../../etc) escapes the base directory after normalization, it throws SecurityException, refusing the upload. Added for issues/9435.
Source
Thrown at jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/CommonUtils.java:74
private static String FILE_NAME_REGEX = "[^A-Za-z\\.\\(\\)\\-()\\_0-9\\u4e00-\\u9fa5]";
public static String uploadOnlineImage(byte[] data,String basePath,String bizPath,String uploadType){
String dbPath = null;
String fileName = "image" + Math.round(Math.random() * 100000000000L);
//update-begin---author:wangshuai---date:2026-01-08---for:【QQYUN-14535】ai生成图片的后缀不一致的,导致不展示---
fileName += "." + PoiPublicUtil.getFileExtendName(data).toLowerCase();
//update-end---author:wangshuai---date:2026-01-08---for:【QQYUN-14535】ai生成图片的后缀不一致的,导致不展示---
try {
if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){
//update-begin---author:wangshuai---date:2026-03-30---for:【issues/9435】uploadOnlineImage路径遍历漏洞修复---
// 1. 使用已有的路径遍历检查
SsrfFileTypeFilter.checkPathTraversal(bizPath);
// 2. 标准化路径并校验是否在basePath范围内
Path root = Paths.get(basePath).toAbsolutePath().normalize();
Path targetDir = root.resolve(bizPath).toAbsolutePath().normalize();
if (!targetDir.startsWith(root)) {
log.error("检测到路径遍历攻击!非法 bizPath: {}", bizPath);
throw new SecurityException("Illegal access to path outside of base directory.");
}
File file = targetDir.toFile();
//update-end---author:wangshuai---date:2026-03-30---for:【issues/9435】uploadOnlineImage路径遍历漏洞修复---
if (!file.exists()) {
file.mkdirs();// 创建文件根目录
}
String savePath = file.getPath() + File.separator + fileName;
File savefile = new File(savePath);
FileCopyUtils.copy(data, savefile);
dbPath = bizPath + File.separator + fileName;
}else {
InputStream in = new ByteArrayInputStream(data);
String relativePath = bizPath+"/"+fileName;
if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){
dbPath = MinioUtil.upload(in,relativePath);
}else if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){
dbPath = OssBootUtil.upload(in,relativePath);
}View on GitHub (pinned to 96fb33f5ec)
Solutions
- Sanitize bizPath on the client and server: reject '..' segments and absolute paths before calling upload.
- If a legitimate nested path is needed, ensure it is relative and within the upload root.
- Do not forward raw user input as bizPath — map it to a fixed set of allowed subdirectories.
- Confirm basePath is configured to the intended upload root (application.yml upload path).
Example fix
// before — client sends raw user-controlled path bizPath = userInput.folder; // "../../etc" // after — whitelist/map to a safe relative dir bizPath = ALLOWED_FOLDERS.contains(userInput.folder) ? userInput.folder : "default";
Defensive patterns
Strategy: validation
Validate before calling
// Reject traversal in bizPath before calling upload
import org.apache.commons.lang3.StringUtils;
public static String sanitizeBizPath(String bizPath) {
if (bizPath == null || bizPath.contains("..") || bizPath.startsWith("/") || bizPath.startsWith("\\")) {
throw new IllegalArgumentException("Invalid bizPath");
}
return bizPath;
} Type guard
public static boolean isBizPathSafe(String bizPath, Path root) {
Path resolved = root.resolve(bizPath).normalize();
return resolved.startsWith(root);
} Try / catch
try {
CommonUtils.uploadOnlineImage(data, bizPath, uploadType, basePath);
} catch (SecurityException e) {
// log and reject the request with 400
response.sendError(400, "Invalid upload path");
} Prevention
- Never forward raw user input as bizPath.
- Whitelist allowed subdirectories for uploads.
- Run path-traversal checks (SsrfFileTypeFilter.checkPathTraversal) early.
- Keep basePath configured to a dedicated upload root.
When it happens
Trigger: An upload request supplies a bizPath containing traversal sequences (../, ..\, absolute paths, or URL-encoded variants) that, after Path.normalize(), resolves outside the configured upload basePath. This is an attacker-controlled input reaching the filesystem write.
Common situations: Penetration testing / security scans submitting crafted bizPath values; a buggy client constructing bizPath from user input without sanitization; integration with an upstream service that forwards raw paths; a legitimate bizPath that accidentally contains '..' segments.
Related errors
- 非法业务路径,禁止访问上传目录之外的路径: ${bizPath}
- 非法业务路径,禁止访问上传目录之外的路径: ${bizPath}
- 请注意,将要排序的列字段不存在:${column}
- 未获取到用户
- 非法存储路径,路径包含遍历字符: {storePath}
AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14).
Data as JSON: /api/errors/b6bbd50c702891b8.
Report an issue: GitHub.